Статьи

Переход с расширения MySQL на PDO

Это руководство представляет собой практический обзор, который поможет вам начать миграцию существующего PHP-кода с использования более старого расширения MySQL на более новое расширение абстракции базы данных PDO. Я не буду вдаваться во все функции, доступные вам в PDO, но я поделюсь с вами основными методами, которые вам необходимо знать, и предложу несколько советов, чтобы ваша миграция была максимально быстрой и безболезненной.

Во-первых, вы должны понять, где находится PDO в экосистеме PHP. На самом деле существует три способа взаимодействия с базой данных MySQL из PHP: первый — с расширением MySQL, второй — с расширением MySQLi, а третий — с PDO.

Расширение MySQL является старейшим из трех и было исходным вариантом, который разработчики использовали для связи с MySQL. Расширение в настоящее время считается устаревшим в пользу двух других альтернатив из-за улучшений, сделанных в более новых выпусках как PHP, так и MySQL.

MySQLi — это «улучшенное» расширение для работы с базами данных MySQL. Он использует преимущества функций, доступных в более новых версиях сервера MySQL, предоставляет разработчикам как функционально-ориентированный, так и объектно-ориентированный интерфейс и делает несколько других изящных вещей. Если PDO не подходит для вашего проекта, то это расширение, которое вы должны использовать.

Затем самым последним расширением является PDO, которое обозначает «Объекты данных PHP». PDO предлагает API, объединяющий большинство функций, которые ранее были распространены на основные расширения доступа к базе данных, то есть MySQL, PostgreSQL, SQLite, MSSQL и т. Д. Интерфейс предоставляет высокоуровневые объекты для программиста для работы с соединениями с базой данных, запросами и наборами результатов, а низкоуровневые драйверы осуществляют связь и обработку ресурсов с сервером базы данных. Много дискуссий и работы идет о PDO, и он считается подходящим методом работы с базами данных в современном профессиональном коде.

Когда это возможно, я рекомендую людям пропустить посредника, так сказать, и перейти с расширения MySQL на PDO, а не на MySQLi. PDO предлагает согласованный API для работы с различными базами данных, поэтому вам не придется изменять свой код PHP, если вам когда-либо придется использовать другую базу данных. Кроме того, в то время как расширение MySQLi в настоящее время поддерживается, всегда есть вероятность, что оно может быть объявлено устаревшим в будущем. Выбор перехода на PDO теперь означает, что вам не придется переходить на него позже и обновлять свой код дважды. Я использую PDO, и вы тоже должны!

Установка и настройка PDO

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

PDO и специфичный для SQLite драйвер должны быть частью установки PHP по умолчанию начиная с версии 5.1.0, и специфичный для MySQL драйвер по-прежнему должен быть установлен, но большинство дистрибутивов Linux часто имеют разные идеи о том, как PHP следует компилировать и упаковывать. Фактически, многие из основных дистрибутивов теперь упаковывают расширение MySQL, расширение MySQLi и драйвер MySQL PDO вместе в одном пакете. Скорее всего, если вы используете MySQL в такой системе, вероятно, PDO уже настроен для вас.

  • Ubuntu собирает PHP с PDO (но по умолчанию не упаковывает драйвер SQLite) и объединяет расширения и драйвер MySQL. Вы можете установить расширения и драйвер, запустив sudo apt-get install php5-mysql
  • Fedora также связывает расширения и драйвер вместе, но упаковывает PDO как загружаемый модуль. При запуске sudo yum install php-mysqlphp-pdo
  • SUSE является единственным дистрибутивом из трех, который создает PHP так, как команда PHP рекомендует в отношении PDO; они собирают PHP с PDO и включают драйвер SQLite. yast2 --install php5-mysql

В Windows все драйверы PDO включены в папку ext, которая была создана при установке PHP из архива скомпилированного двоичного файла. Вам нужно только обновить php.ini

 extension=php_pdo_mysql.dll

Всегда возможно скомпилировать драйверы самостоятельно в худшем случае. Убедитесь, что библиотеки MySQL и другие файлы разработки установлены и доступны в вашей среде сборки, так как большинство проблем, с которыми люди сталкиваются при попытке что-то скомпилировать, возникает, когда компилятор не может найти различные заголовочные файлы или библиотеки для ссылки.

Основные запросы

Основной рабочий процесс использования функций расширения MySQL для работы с базой данных можно представить как 5-шаговый процесс:

  1. Установите соединение с сервером базы данных и выберите базу данных, с которой вы будете работать
  2. Построить запрос для отправки на сервер
  3. Отправить запрос
  4. Итерация по возвращенным строкам результата
  5. Освободите ресурсы, используемые результатом, и, возможно, соединение с базой данных.
 <?php
// Step 1: Establish a connection
$db = mysql_connect("localhost", "testusr", "secretpass");
mysql_select_db("testdb", $db);

// Step 2: Construct a query
$query = "SELECT * FROM foo WHERE bar = '" . mysql_real_escape_string($zip) . "'";

// Step 3: Send the query
$result = mysql_query($query, $db);

// Step 4: Iterate over the results
while($row = myql_fetch_assoc($result)) {
    print_r($row);
}

// Step 5: Free used resources
mysql_free_result($result);
mysql_close($db);

С PDO можно выполнить тот же процесс, который выглядит следующим образом:

 <?php
// Step 1: Establish a connection
$db = new PDO("mysql:host=localhost;dbname=testdb", "testusr", "secretpass");

// Step 2: Construct a query
$query = "SELECT * FROM foo WHERE bar = " . $db->quote($zip);

// Step 3: Send the query
$result = $db->query($query);

// Step 4: Iterate over the results
while($row = $result->fetch(PDO::FETCH_ASSOC)) {
    print_r($row);
}

// Step 5: Free used resources
$result->closeCursor();
$db = null;

Процесс подключения к серверу и выбора базы данных с помощью PDO выполняется с использованием DSN вместо myql_connect()mysql_select_db() DSN — это сокращение от «Data Source Name», которое представляет собой строку, которая определяет, какой драйвер PDO использовать для связи с базой данных, и передает любую важную информацию о соединении, такую ​​как хост-сервер, порт соединения и имя базы данных. В зависимости от вашей базы данных формат предоставленного вами DSN может отличаться. Основные компоненты, необходимые для каждого драйвера, описаны на php.net, но, к сожалению, их иногда сложно найти. Я рекомендую использовать функцию поиска по сайту, чтобы найти термин «DSN» в онлайн-документации .

Также обратите внимание, что PDO::quote()и заключает в кавычки значение, тогда как mysql_real_escape() Вы должны помнить об этом, чтобы в конечном запросе не возникало лишних кавычек, и не ломайте голову над вопросом, откуда они взялись.

Хотя иногда вы можете обойтись без освобождения ресурса результатов с помощью mysql_free_result() Если у вас все еще есть результирующий набор из запроса SELECTcloseCursor()INSERTUPDATE Лучше выработать привычку делать все правильно, чтобы избежать неприятных ситуаций позже.

Копать (немного) глубже

То, что было сделано до сих пор, достаточно для того, чтобы вы начали как можно быстрее и безболезненно переносить ваше PHP-приложение с MySQL на PDO, но это больше, чем то, что я вам показал. Я хотел бы также выделить несколько других функций PDO, которые могут оказаться полезными: подготовленные операторы и обработка ошибок.

Подготовленные заявления

Подготовленный оператор — это представление запроса в виде объекта. Преимущество представления запроса в виде объекта состоит в том, что с ним может быть связана дополнительная логика, которой в противном случае было бы трудно управлять для представления плоской строки. Например, вы можете указать заполнители в запросе, которые затем будут привязаны к переменным в вашем скрипте. Это полезно, если вы выполняете один и тот же запрос несколько раз, чтобы удовлетворить запрос, но с другими параметрами. Запрос должен быть подготовлен только один раз, но его можно запускать много раз с разными значениями при изменении значений переменных.

 <?php
// collection of user information to import into the database
$users = ...

// specify the query "template"
$query = $db->prepare("INSERT INTO users (first_name, last_name, email) VALUES (:fname, :lname, :email)");

// bind the placeholder names to specific script variables
$query->bindParam(":fname", $firstName);
$query->bindParam(":lname", $lastName);
$query->bindParam(":email", $email);

// assign values to the specific variables and execute the query
foreach ($users as $u) {
    $firstName = $u["first_name"];
    $lastName = $u["last_name"];
    $email = $u["email"];
    $query->execute();
}

Параметры не должны заключаться в кавычки или экранироваться с помощью подготовленных операторов, потому что базовый драйвер автоматически заключает в кавычки и экранирует любые связанные параметры для вас. Из-за этого многим людям нравится использовать подготовленные операторы для защиты от уязвимостей SQL-инъекций, даже если запрос выполняется только один раз.

Обработка ошибок

Вы можете указать одну из трех различных парадигм обработки ошибок с помощью PDO, используя PDO::setAttribute()

 <?php
$db = new PDO($dsn, $user, $passwd);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Режимы:

  • Silent Mode ( PDO::ERRMODE_SILENT
  • Режим предупреждения ( PDO::ERRMODE_WARNING
  • Режим исключения ( PDO::ERRMODE_EXCEPTION

Независимо от того, какой режим установлен, есть внутренний код ошибки, который установлен, и вы можете проверить, используя errorCode()errorInfo()PDOPDOStatement Они аналогичны mysql_errno()mysql_error() errorCode()5-символьную строку, как определено в ANSI SQL-92 . errorInfo()

 <?php
$query = "SELECT * FROM foo WHERE MALFORMED QUERY";
$result = $db->query($query);
$error = $db->errorInfo();
if (!is_null($error[2])) {
    echo "Query failed! " . $error[2];
}
...

Если вы используете режим исключения, описание того, что пошло не так, доступно через метод getMessage()

 <?php
$query = "SELECT * FROM foo WHERE MALFORMED QUERY";
try {
    $result = $db->query($query);
    ...
}
catch (PDOException $e) {
    echo $e->getMessage();
}

Резюме

Теперь у вас должны быть базовые знания, необходимые для начала перехода с более старого расширения MySQL на более новое расширение PDO. Вы видели, что в большинстве случаев PDO уже доступен, его легко настроить, если по какой-то причине это не так. Вы также видели, как легко подключиться к серверу базы данных MySQL, выполнять запросы и получать результаты. Конечно, это был просто практический обзор; Чтобы узнать больше о том, что может предложить PDO и как вы можете этим воспользоваться, я рекомендую вам ознакомиться с доступной документацией на php.net.

Изображение через Дирк Эркен / Shutterstock