Как использовать PDO в PHP для работы с MySQL и другими СУБД

0 14 января 2026

PDO — это лёгкий, унифицированный интерфейс для работы с разными СУБД в PHP. Он не заменяет драйвер базы, а предоставляет общий набор методов для подключения, выполнения запросов и работы с результатами, что упрощает переносимость кода между базами.


Почему стоит выбрать PDO

  • Единый API для разных СУБД (MySQL, PostgreSQL, SQLite и др.).
  • Поддержка подготовленных выражений (prepared statements) — главная защита от SQL-инъекций и удобство повторного выполнения запросов.
  • Управление транзакциями, режимы ошибок и гибкие режимы извлечения данных.

Быстрое подключение (DSN, конструктор и опции)
Подключение создаётся через конструктор PDO, в котором первым параметром идёт DSN (Data Source Name), затем пользователь и пароль, а также опции.


Подготовленные выражения (prepared statements) 
Prepared statements работают в две фазы: подготовка (prepare) и выполнение (execute). Это позволяет безопасно подставлять значения в запрос и избегать ручной экранизации. PDO может эмулировать подготовленные выражения, если драйвер их не поддерживает.



Важно: нельзя смешивать в одном SQL-шаблоне позиционные и именованные плейсхолдеры — это вызовет ошибку. (Выбирайте один стиль для запроса.)

Привязка параметров: bindParam vs bindValue

bindValue($param, $value, $type) — привязывает значение сразу. Полезно для литералов.

bindParam($param, $var, $type) — привязывает переменную по ссылке; значение будет прочитано при execute() (удобно, если переменная меняется перед выполнением).

$stmt = $pdo->prepare('UPDATE accounts SET balance = :bal WHERE id = :id');
$stmt->bindValue(':bal', 100.5, PDO::PARAM_STR);
$stmt->bindValue(':id', 42, PDO::PARAM_INT);
$stmt->execute();


Режимы получения данных (fetch modes)

PDO::FETCH_ASSOC — ассоц. массив (['id'=>1, 'name'=>'x'])

PDO::FETCH_NUM — нумерованный массив

PDO::FETCH_OBJ — объект ($row->name)

PDO::FETCH_CLASS — заполнить экземпляр класса



Транзакции
Если нужны атомарные изменения — используйте транзакции: beginTransaction(), commit(), rollBack(). Не каждая СУБД поддерживает транзакции — проверяйте поведение драйвера.



Обработка ошибок и режимы ошибок
Рекомендуется использовать режим PDO::ERRMODE_EXCEPTION — тогда PDO бросает PDOException, и ошибки легче отлавливать и логировать. Альтернативы: PDO::ERRMODE_SILENT (по умолчанию) и PDO::ERRMODE_WARNING.

Небольшие советы по безопасности и стабильности
  • Всегда используйте подготовленные выражения для подстановки пользовательских данных.
  • Выключайте эмуляцию подготовленных выражений (PDO::ATTR_EMULATE_PREPARES => false) при работе с MySQL, если хотите, чтобы драйвер использовал нативные prepared statements (иногда это важно для типов данных и производительности).
  • Устанавливайте charset в DSN (charset=utf8mb4 для MySQL), чтобы избежать проблем с кодировкой.
  • Логируйте ошибки, но не выводите детальные сообщения с SQL в публичный интерфейс.


Общие ошибки и ловушки

  • Смешивание именованных и позиционных плейсхолдеров в одном запросе.

  • Ожидание, что PDO сам по-умолчанию бросает исключения (нужно явно установить ATTR_ERRMODE).

  • Использование exec() вместо prepare/execute() для запросов с пользовательскими данными — риск инъекций.


Мини-класс-обёртка (простой и безопасный пример)

<?php
class DB {
    private static ?PDO $pdo = null;

    public static function getPDO(): PDO {
        if (self::$pdo === null) {
            $dsn = 'mysql:host=127.0.0.1;dbname=testdb;charset=utf8mb4';
            $opts = [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_EMULATE_PREPARES => false,
            ];
            self::$pdo = new PDO($dsn, 'dbuser', 'dbpass', $opts);
        }
        return self::$pdo;
    }

    public static function fetchAll(string $sql, array $params = []): array {
        $stmt = self::getPDO()->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetchAll();
    }
}


Короткое резюме (что важно помнить) 

PDO — универсальный, безопасный и гибкий инструмент для работы с БД в PHP. Используйте подготовленные выражения и режим ошибок ERRMODE_EXCEPTION. Транзакции — для атомарных операций; всегда оборачивайте в try/catch и откатывайте при ошибке.


🙏 Благодарностей 0
Привет! Похоже, Вы ещё не вошли на сайт.
Чтобы получить полный доступ, зарегистрируйтесь или войдите под своим именем.