PHP 8.4.1 Released!

Драйвер PDO_MYSQL: функции БД MySQL

Введение

PDO_MYSQL — драйвер, через который PHP получает доступ к базам данных MySQL. Для этого драйвер реализует интерфейс модуля PDO.

Драйвер PDO_MYSQL по умолчанию использует эмулированную подготовку.

MySQL 8

При запуске PHP до версии 7.1.16 или PHP с версии 7.2 до версии 7.2.4 в качестве плагина шифрования паролей по умолчанию для сервера MySQL 8 устанавливают mysql_native_password, иначе выдаётся ошибка наподобие The server requested authentication method unknown to the client [caching_sha2_password], даже когда плагин caching_sha2_password не задали.

Причина этого состоит в том, что на сервере MySQL 8 в качестве плагина по умолчанию указан caching_sha2_password, который не распознаётся старыми выпусками PHP (драйвером mysqlnd). Вместо него в файле конфигурации сервера my.cnf указывают — default_authentication_plugin=mysql_native_password. Плагин caching_sha2_password получил полную поддержку начиная с PHP 7.4.4. В предыдущих версиях PHP его поддерживает модуль mysql_xdevapi.

Внимание

Осторожно: MySQL-таблицы подсистемы хранения данных не поддерживают транзакции. БД MySQL сделает вид, что транзакция успешно началась, если в коде, который работает с транзакционной базой данных, указали таблицу, которая не поддерживает транзакции. Кроме того, каждый выполненный DDL-запрос будет неявно фиксировать незавершённые транзакции — то есть завершать открытые транзакции и выполнять стек незавершённых запросов.

Замечание:

Драйвер MySQL неправильно обрабатывает бит PDO::PARAM_INPUT_OUTPUT в методе PDOStatement::bindParam(); хотя такие параметры и разрешается указывать, они не обновляются (т. е. фактический вывод игнорируется).

Установка

Обычно установочные пакеты Unix имеют в своём составе бинарные пакеты PHP. Несмотря на то, что эти бинарные пакеты обычно собраны с поддержкой модуля MySQL, может понадобиться установка библиотек модулей отдельно. Проверьте свой дистрибутив на наличие нужных библиотек через пакетный менеджер.

К примеру, на Ubuntu установка пакета php5-mysql устанавливает модули ext/mysql, ext/mysqli, и PDO_MYSQL. На CentOS пакет php-mysql также устанавливает эти три модуля.

Также вы всегда можете скомпилировать необходимые модули самостоятельно. Сборка PHP из исходных кодов позволит вам собрать именно те модули MySQL, которые вам нужны, а также выбрать нужную клиентскую библиотеку для каждого модуля.

Используйте --with-pdo-mysql[=DIR] для установки модуля PDO MySQL, где необязательный параметр [=DIR] указывает директорию, где установлена MySQL. По умолчанию используется библиотека mysqlnd. Более детальный разбор по выбору библиотеки можно почитать в разделе "Выбор библиотеки MySQL".

Дополнительный параметр --with-mysql-sock[=DIR] указывает расположение unix-сокета MySQL для всех MySQL модулей, включая PDO_MYSQL. Если параметр не указан, поиск производится в директориях по умолчанию.

Дополнительный параметр --with-zlib-dir[=DIR] используется как префикс пути к libz.

$ ./configure --with-pdo-mysql --with-mysql-sock=/var/mysql/mysql.sock

Поддержка SSL включается, используя соответствующую константу PDO_MySQL, которая эквивалентна вызову » API MySQL-функции mysql_ssl_set() в C. К тому же SSL не может быть включён с помощью PDO::setAttribute, потому что соединение уже существует. Смотрите документацию MySQL о » подключении к MySQL с SSL.

Предопределённые константы

Драйвер определяет перечисленные константы, которые доступны только тогда, когда PHP собрали с поддержкой этого модуля, или модуль динамически загрузили во время исполнения кода. Константы, которые зависят от драйвера, разрешается использовать только совместно с драйвером. Атрибуты одного драйвера с другим драйвером ведут себя неожиданно. Чтобы проверить название драйвера, которое содержит атрибут PDO::ATTR_DRIVER_NAME, вызывают метод PDO::getAttribute(), если код запускается с несколькими драйверами.

PDO::MYSQL_ATTR_USE_BUFFERED_QUERY (bool)
По умолчанию запросы выполняются в буферизованном режиме. Драйвер MySQL будет использовать небуферизованный режим, если для объекта PDO значение этого атрибута установить как false.

Пример #1 Установка небуферизованного режима MySQL

<?php

$pdo
= new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_password');
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

$unbufferedResult = $pdo->query("SELECT Name FROM City");
foreach (
$unbufferedResult as $row) {
echo
$row['Name'] . PHP_EOL;
}

?>

PDO::MYSQL_ATTR_LOCAL_INFILE (int)

Включить LOAD LOCAL INFILE.

Обратите внимание, что эту константу можно использовать только в массиве driver_options при создании дескриптора новой базы данных.

PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY (string)

Позволяет ограничить загрузку LOCAL DATA файлами, расположенными в указанном каталоге. Доступно, начиная с версии PHP 8.1.0.

Обратите внимание, что эта константа может использоваться только в массиве driver_options при создании нового дескриптора базы данных.

PDO::MYSQL_ATTR_INIT_COMMAND (string)

Команда, которую необходимо выполнить при подключении к MySQL-серверу. Также будет автоматически выполнена при переподключении.

Обратите внимание, что эта константа может быть использована только в массиве driver_options при создании дескриптора новой базы данных.

PDO::MYSQL_ATTR_READ_DEFAULT_FILE (int)

Чтение именованных параметров из файла my.cnf. Эта опция недоступна, если используется mysqlnd, потому что mysqlnd не читает файлы конфигурации MySQL.

PDO::MYSQL_ATTR_READ_DEFAULT_GROUP (int)

Чтение именованной группы параметров из файла my.cnf или из файла, определённого в константе MYSQL_READ_DEFAULT_FILE. Эта опция недоступна, если используется mysqlnd, потому что mysqlnd не читает файлы конфигурации MySQL.

PDO::MYSQL_ATTR_MAX_BUFFER_SIZE (int)

Максимальный размер буфера. По умолчанию равен 1 Мб. Эта константа не поддерживается при компиляции вместе с mysqlnd.

PDO::MYSQL_ATTR_DIRECT_QUERY (int)

Выполнять прямые запросы, не использовать подготовленные конструкции.

PDO::MYSQL_ATTR_FOUND_ROWS (int)

Возвращает количество найденных (совпавших) строк, а не количество изменённых строк.

PDO::MYSQL_ATTR_IGNORE_SPACE (int)

Разрешает пробелы после имён функций. Делает все имена функций зарезервированными словами.

PDO::MYSQL_ATTR_COMPRESS (int)

Включить сжатие сетевого соединения.

PDO::MYSQL_ATTR_SSL_CA (int)

Путь к файлу сертификата SSL.

PDO::MYSQL_ATTR_SSL_CAPATH (int)

Путь к директории, которая содержит SSL-сертификаты доверенных центров (CA), хранящиеся в формате PEM.

PDO::MYSQL_ATTR_SSL_CERT (int)

Путь к файлу с SSL-сертификатом.

PDO::MYSQL_ATTR_SSL_CIPHER (int)

Список из одного или более допустимых шифров для использования в SSL-шифровании в формате, который понимает OpenSSL. Например: DHE-RSA-AES256-SHA:AES128-SHA

PDO::MYSQL_ATTR_SSL_KEY (int)

Путь к файлу с ключом SSL.

PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT (int)

Предлагает способ отключения проверки SSL-сертификата сервера. Эта опция доступна только с драйвером mysqlnd.

Существует начиная с PHP 7.0.18 и PHP 7.1.4.

PDO::MYSQL_ATTR_MULTI_STATEMENTS (int)

Если установлено как false, запрещает запуск множественных запросов, как для PDO::prepare(), так и для PDO::query().

Обратите внимание, что эта константа может быть использована только в массиве driver_options при создании нового дескриптора БД.

Настройка во время выполнения

Поведение функций зависит от установок в файле php.ini.

Опции конфигурации PDO_MYSQL
Имя По умолчанию Место изменения
pdo_mysql.default_socket "/tmp/mysql.sock" INI_SYSTEM
pdo_mysql.debug NULL INI_SYSTEM
Дополнительную информацию и определения режимов INI_* даёт раздел «Места установки параметров конфигурации».

Краткое разъяснение конфигурационных директив.

pdo_mysql.default_socket string

Устанавливает сокет домена UNIX. Эту опцию необходимо указать во время компиляции, если сокет домена найден во время конфигурирования. Эта настройка только для Unix.

pdo_mysql.debug bool

Разрешает отладку для PDO_MYSQL. Эта настройка доступна только, если PDO_MYSQL скомпилирован с "mysqlnd" и в режиме отладки PDO.

Содержание

Добавить

Примечания пользователей 6 notes

up
13
Desislav Kamenov
6 years ago
There is an important undocumented attribute which disables certificate CN verification available after
5.6.22 (not sure), 7.0.18 (verified) and 7.1.15 (not sure)

PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT

possible values: true, false
default value: true

Related PHP bugs:
https://bugs.php.net/bug.php?id=71845
https://bugs.php.net/bug.php?id=71003

and github PR: https://github.com/php/php-src/pull/1913
up
7
davey at php dot net
17 years ago
To use "PDO::MYSQL_ATTR_USE_BUFFERED_QUERY" you should call
PDO::setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);

It will not work when passed into PDO::prepare()
up
6
brian at diamondsea dot com
16 years ago
SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. ...

After spending hours trying to track down why we were getting this error on a new server, after the same code ran fine on other servers, we found the problem to be an old MySQL _client_ library running on our web server, and a latest-version MySQL _server_ running on the database server's box.

Upgraded the MySQL client on the web server to the current revision and the problem went away.
up
2
curt at webmasterbond dot com
13 years ago
Today's PHP snapshot now has SSL support for PDO. Follow the directions here ( http://dev.mysql.com/doc/refman/5.0/en/secure-create-certs.html ) to set up MySQL and then use the following connection options:

<?php
$pdo
= new PDO(
'mysql:host=hostname;dbname=ssldb',
'username',
'password',
array(
PDO::MYSQL_ATTR_SSL_KEY =>'/path/to/client-key.pem',
PDO::MYSQL_ATTR_SSL_CERT=>'/path/to/client-cert.pem',
PDO::MYSQL_ATTR_SSL_CA =>'/path/to/ca-cert.pem'
)
);
?>
up
0
snoyes at gmail dot com
22 days ago
> change it by setting default_authentication_plugin=mysql_native_password in my.cnf

This only works in MySQL 8.0. The default_authentication_plugin variable has been removed from 8.4.
up
-3
rmottey at gmail dot com
16 years ago
I have been getting the error below when performing multiple queries within a single page.

Setting the attribute below did not seem to work for me.

So building on previous example i am initilizing my stmt variable on every query and a fetch all into an array. Seems to be working for me.

Error:
PDO Error 1.1: Array ( [0] => xxx[1] => yyy[2] => Lost connection to MySQL server during query )

Fix:

(PDO::setAttribute("PDO::MYSQL_ATTR_USE_BUFFERED_QUERY", true);)

<?

try {
$dbh = new PDO('mysql:host=xxx;port=xxx;dbname=xxx', 'xxx', 'xxx', array( PDO::ATTR_PERSISTENT => false));
$stmt = $dbh->prepare("CALL getname()");

// call the stored procedure
$stmt->execute();
// fetch all rows into an array.
$rows = $stmt->fetchAll();
foreach ($rows as $rs)
{
$id = $rs['id'];
}
//initilise the statement
unset($stmt);
$stmt = $dbh->prepare("call secondprocedure(?);");
$stmt->bindValue(1, $id);
if ( ! $stmt->execute() )
{
echo "PDO Error 1.1:\n";
print_r($stmt->errorInfo());
exit;
}
unset($stmt);
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
?>
To Top