Работа с базами данных через PDO

Symbool

Регистрация
17.01.16
Сообщения
27
Симпатии
14
#1
Защиты данных пользователей всегда была приоритетом разработчика. Ведь особо умные, но нечестные товарищи ну уж очень любят коммуниздить данные пользователей чужих проектов и юзать их в собственных низменных целях.
Самой распространенной уязвимостью, позволяющей получить данные пользователей вне ведома владельца ресурсов является SQL Injection, или же SQL иньекция - несанкционированная модификация запроса к базе данных, позволяющая получить помимо задуманных разработчиком данных - еще и нужные злоумышленнику.

Раньше, когда под рукой в PHP мы имели лишь пресловутые и корявые функции mysql_* приходилось городить лесоповал из различных фильтров, обрабатывающих входящие данные и предотвращающие несанкционированную модификацию SQL-запросов. Сейчас же, благодаря стараниям наших братьев-программистов имеется кучи классов и драйверов, позволяющих особо не заморачиваться с обработкой данных. Об одном из таких вот классов-драйверов сегодня и поговорим, а именно, о PDO.

Особо революционных отличий от того же, к примеру, mysqli здесь нет, но все же он, как мне кажется, намного удобнее в плане работы. Но тут уж на вкус и цвет товарисчей нет.

Что же умеет PDO? Да все то же, что и другие современные драйверы для работы с базами данных - быстрые запросы, преподготовленные запросы и бинд данных, реалконнекты и прочее. Кому интересны все возможности драйвера могут покурить официальную документацию здесь:

Пожалуйста, войдите или зарегистрируйтесь для просмотра текста.


Я же покажу примеры использования сего драйвера, в чем его удобство и самые частоиспользуемые его функции.

Итак, де-факто сам PDO после вызова является объектом класса, и имеет свои методы. Сегодня мы разберем такие его методы, как prepare(), query(), exec(), execute(), bindParam(), bindValue()

О каждом из методов поговорим отдельно.

Итак, начнем, наверное, с самого простого.

Перед тем, как начать работать с PDO из своего кода необходимо создать объкт класса PDO и создать соединение с базой данных. Сделать это можно, например, так:

Код:
try { // Пробуем подключиться с возмоностью отловить исключения \ ошибки
  $db = new PDO('mysql:host=адрес сервера SQL;dbname=имя базы','пользователь','пароль'); // Создаем объект класса с нашими данными БД
 }  // Если есть ошибки 
catch(PDOException $e) { 
//Закончим обработку скрипта
  die("Ошибка: ".$e->getMessage()); 
}
Тут ничего особо непонятного нет, так что перейдем к основным используемым методам PDO

1. query() - метод предназначен для отправки запросов без предварительной обработки данных. Т.е. является аналогом стандартной функции mysql_query()

Пример использования
Код:
$db-> query("SELECT * FROM `table` WHERE `user_group` = 5");
2. exec() - метод, предназначенный для. скажем так, "системных" запросов. К примеру, для сообщения серверу БД кодировки для обмена данных и т.д
Пример использования:
Код:
$db->exec("SET NAMES UTF-8");
В принципе, с exec() можно использовать и любые другие запросы. Отличие его от того же query() является то, что метод не возвращает выбранных данных, а лишь количество затронутых запросом строк.
Что бы было понятнее, еще пример:
Код:
$count = $db->exec("SELECT * FROM `table` WHERE `user_group` = 5");
echo $count; // Предположим, что в таблице 70 записей с user_group = 5, соответственно, $count отдаст 70. И все.
3. Prepare() - самый вкусный метод, позволяющий создавать предподготовленные запросы, проводить бинд (обработку) данных и т.д. Вот он наш щит от кулцхацкиров, жаждущих наших БД. Враг не пройдет!
Итак, предподготовленный запрос, это запрос, который создан один раз, и далее используется столько, сколько нужно, но с разными данными.
Бинд данных в нашем конкретном случае - обработка данных под 1 - нужный тип данных, 2 - сопоставление переменных с плейсхолдерами в предподготовленном запросе.

В PDO бинд может быть односторонним и двусторонним. Односторонний бинд предполагает использование обработанной переменной только внутри того запроса, где она биндится, двусторонний же дает возможность использовать ее и вне запроса.

Покажу пример с односторонним биндом.

Код:
//Получаем что нибудь, например, с GET-запросом
$id = $_GET['id'];
// Подгатавливаем запрос
$pre = $db->prepare("SELECT * FROM `table` WHERE `user_group` = :id"); // Здесь ID - плейсхолдер
// Проводим односторонний бинд
$pre->bindParam(":id", $id, PDO::PARAM_INT); // Проводим бинд данных, привязываем переменную $id к плейсхолдеру :id и указываем, что данные должны иметь тип INTEGER, т.е. - целое число
$pre-> execute(); // Отправляем запрос

// Преобразуем данные из bool в  ассоц.массив
$pre = $pre->fetch(PDO::FETCH_ASSOC);
// Ну и работаем с ними, как хотим
foreach($pre as $p){
// CODE
}
Работа с двусторонним биндом происходит через метод bindValue(), параметры указываются аналогично bindParam().

Думаю, как Вы уже догадались из кода выше, данные после запроса необходимо обработать, и как успели заметить, происходит это при помощи метода fetch() ( хотя есть и другие, но это, так сказать, базис)
Три основных типа данных, в которые можно преобразовать, это:
OBJ - преобразует данные в объект.
ASSOC - преобразует данные в ассоциативный массив
BOTH - смесь индексированного массива с ассоциативным.


Вроде бы все рассказал, что хотел.
Кидайтесь тапками, задавайте вопросы, постараюсь всем ответить и помочь.
Спасибо за внимание.
 

MiLLa

Регистрация
22.12.16
Сообщения
1
Симпатии
0
#2
Интересный подход к проблеме, да вы правы на заре сайтостроения для защиты БД все извращались как могли с защитой своих БД. Масса подходов используется и сейчас для противостояния подобным угрозам. Но и SQL -injection тоже не стоит на месте извращенность ума и доступность информации делает свое дело. Согласен с Вами что Prepare() - самый вкусный метод и что он подкупает своей возможностью позволяя создавать предподготовленные запросы, но как известно всего не предусмотреть. Последнее время бывшие сливщики БД вообще не замачиваются и не утруждают себя работой, дошли уже до того что тупо просят ваш пароль и логин от вашего аккаунта на форуме и тупо сливают его в паблик за определенные отступные для вас.
Статья автора действительно не рядовое решения и весьма полезна за что ему огромная благодарность.
 

Nor_Myasnick

Регистрация
22.12.16
Сообщения
7
Симпатии
1
#3
Сам сталкивался с хакерами - не раз ломали . Сейчас использую платную защиту для БД и вроде бы никаких нареканий пока нет)
 

qklyGOD

Регистрация
16.04.17
Сообщения
9
Симпатии
0
#4
Круто! Сейчас попробую. Кажется, что код станет на порядок красивее =)