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

Тема в разделе "PHP Pro", создана пользователем Symbool, 18.01.16.

  1. Symbool

    Symbool Участник

    Сообщения:
    29
    Репутация:
    11
    Рейтинг:
    +13 / -0
    Защиты данных пользователей всегда была приоритетом разработчика. Ведь особо умные, но нечестные товарищи ну уж очень любят коммуниздить данные пользователей чужих проектов и юзать их в собственных низменных целях.
    Самой распространенной уязвимостью, позволяющей получить данные пользователей вне ведома владельца ресурсов является 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 - смесь индексированного массива с ассоциативным.


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