Введение
Модуль Объекты данных PHP ( PDO ) определяет простой и согласованный интерфейс для доступа к базам данных в PHP. Каждый драйвер базы данных, в котором реализован этот интерфейс, может представить специфичную для базы данных функциональность в виде стандартных функций модуля. Но надо заметить, что сам по себе модуль PDO не позволяет манипулировать доступом к базе данных. Чтобы воспользоваться возможностями PDO, необходимо использовать соответствующий конкретной базе данных PDO драйвер.
PDO обеспечивает абстракцию доступу к данным, это значит, что вне зависимости от того, какая конкретная база данных используется, вы можете пользоваться одними и теми же функциями для выполнения запросов и выборки данных. PDO не абстрагирует саму базу данных, этот модуль не переписывает SQL-запросы и не эмулирует отсутствующий в СУБД функционал. Если нужно именно это, необходимо воспользоваться полноценной абстракцией базы данных.
Модуль PDO внедрён в PHP.
User Contributed Notes
There are no user contributed notes for this page.
- PDO
- Введение
- Установка и настройка
- Предопределённые константы
- Подключения и управление подключениями
- Транзакции и автоматическая фиксация изменений
- Подготовленные запросы и хранимые процедуры
- Ошибки и их обработка
- Большие объекты (LOB)
- PDO
- PDOStatement
- PDOException
- Драйверы PDO
- Copyright © 2001-2023 The PHP Group
- My PHP.net
- Contact
- Other PHP.net sites
- Privacy policy
PHP PDO быстрый старт, работа с MySQL
PDO (PHP Data Objects) — расширение PHP, которое реализует взаимодействие с базами данных при помощи объектов. Профит в том, что отсутствует привязка к конкретной системе управления базами данных. PDO поддерживает СУБД: MySQL, PostgreSQL, SQLite, Oracle, Microsoft SQL Server и другие.
Официальный мануал по PHP PDO здесь . Там же можно найти и сам класс PDO .
Почему стоит использовать PDO
Функции mysql в PHP для работы с БД давно уже устарели, на сегодняшний день желательно использовать mysqli или PDO (PHP Data Objects). Кроме того, mysqli — эта библиотека, которая по большому счёту, не предназначена для использования напрямую в коде. Она может послужить хорошим строительным материалом для создания библиотеки более высокого уровня. При работе с mysqli следует также помнить об обеспечении безопасности вашего приложения, в частности о защите от SQL-инъекций. В случае использования PDO (с его подготовленными запросами), такая защита идёт уже «из коробки», главное правильно применить необходимые методы.
Тестовая база данных с таблицей
CREATE DATABASE `pdo` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE pdo-test; CREATE TABLE categories ( id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id), name VARCHAR(255) NOT NULL ); INSERT INTO `categories` (`name`) VALUES ('Ноутбуки и планшеты'), ('Компьютеры и периферия'), ('Комплектующие для ПК'), ('Смартфоны и смарт-часы'), ('Телевизоры и медиа'), ('Игры и приставки'), ('Аудиотехника'), ('Фото-видеоаппаратура'), ('Офисная техника и мебель'), ('Сетевое оборудование'), ('Крупная бытовая техника'), ('Товары для кухни'), ('Красота и здоровье'), ('Товары для дома'), ('Инструменты'), ('Автотовары');Установка PDO
// Установка в Linux sudo apt update sudo apt install mysql-server sudo apt install php-mysql sudo apt install pdo-mysql // В php.ini добавить extension=pdo.so extension=pdo_mysql.so // На Windows, как правило драйвер уже установлен, нужно просто проверить включен ли он в php.ini extension=php_pdo_mysql.dllПроверить доступные драйвера
print_r(PDO::getAvailableDrivers());Соединение с базой данных
Соединения устанавливаются автоматически при создании объекта PDO от его базового класса.
// Пример #1. Простое подключение $db = new PDO('mysql:host=localhost;dbname=pdo', 'root', 'password');При ошибке подключения PHP выдаст ошибку:
Fatal error: Uncaught PDOException: .// Пример #2. Обработка ошибок подключения try < $dbh = new PDO('mysql:host=localhost;dbname=pdo', 'root', 'password'); >catch (PDOException $e) < print "Error!: " . $e->getMessage(); die(); >Подготовленные и прямые запросы
В PDO два способа выполнения запросов:
- Прямой — состоит из одного шага;
- Подготовленный — состоит из двух шагов.
Прямые запросы
- query() используется для операторов, которые не вносят изменения, например SELECT . Возвращает объект PDOStatemnt , из которого с помощью методов fetch() или fetchAll извлекаются результаты запроса. Можно его сравнить с mysql resource , который возвращала mysql_query() .
- exec() используется для операторов INSERT, DELETE, UPDATE . Возвращает число обработанных запросом строк.
Прямые запросы используются только в том случае, если в запросе отсутствуют переменные и есть уверенность, что запрос безопасен и правильно экранирован.
$stmt = $db->query("SELECT * FROM categories"); while ($row = $stmt->fetch()) < echo ''; print_r($row); >
Подготовленные запросы
Если же в запрос передаётся хотя бы одна переменная, то этот запрос в обязательном порядке должен выполняться только через подготовленные выражения . Что это значит? Это обычный SQL запрос, в котором вместо переменной ставится специальный маркер — плейсхолдер. PDO поддерживает позиционные плейсхолдеры ( ? ), для которых важен порядок передаваемых переменных, и именованные ( :name ), для которых порядок не важен. Примеры:
$sql = "SELECT name FROM categories WHERE = "SELECT name FROM categories WHERE name = :name";Чтобы выполнить такой запрос, сначала его надо подготовить с помощью метода prepare() . Она также возвращает PDO statement , но ещё без данных. Чтобы их получить, надо исполнить этот запрос, предварительно передав в него наши переменные. Передать можно двумя способами: Чаще всего можно просто выполнить метод execute() , передав ему массив с переменными:
$stmt = $pdo->prepare("SELECT `name` FROM categories WHERE `id` = ?"); $stmt->execute([$id]); $stmt = $pdo->prepare("SELECT `name` FROM categories WHERE `name` = :name"); $stmt->execute(['name' => $name]);Как видно, в случае именованных плейсхолдеров в execute() должен передаваться массив, в котором ключи должны совпадать с именами плейсхолдеров. После этого можно извлечь результаты запроса:
$id = 1; $stmt = $db->prepare("SELECT * FROM categories WHERE `id` = ?"); $stmt->execute([$id]); $category = $stmt->fetch(PDO::FETCH_LAZY); echo ''; print_r($category);
Важно! Подготовленные запросы - основная причина использовать PDO, поскольку это единственный безопасный способ выполнения SQL запросов, в которых участвуют переменные.
Получение данных. Метод fetch()
Мы уже выше познакомились с методом fetch() , который служит для последовательного получения строк из БД. Этот метод является аналогом функции mysq_fetch_array() и ей подобных, но действует по-другому: вместо множества функций здесь используется одна, но ее поведение задается переданным параметром. В подробностях об этих параметрах будет написано в другой заметке, а в качестве краткой рекомендации посоветую применять fetch() в режиме FETCH_LAZY
$id = 1; $stmt = $db->prepare("SELECT * FROM categories WHERE `id` = ?"); $stmt->execute([$id]); while ($row = $stmt->fetch(PDO::FETCH_LAZY)) < echo 'Category name: '.$row->name; >В этом режиме не тратится лишняя память, и к тому же к колонкам можно обращаться любым из трех способов - через индекс, имя, или свойство (через -> ). Недостатком же данного режима является то, что он не работает с fetchAll()
Получение данных. Метод fetchColumn()
Также у PDO statement есть метод для получения значения единственной колонки. Очень удобно, если мы запрашиваем только одно поле - в этом случае значительно сокращается количество кода:
$id = 1; $stmt = $db->prepare("SELECT `name` FROM categories WHERE `id` = ?"); $stmt->execute([$id]); $name = $stmt->fetchColumn(); echo 'Category name: '.$name;Получение данных. Метод fetchAll()
$data = $db->query("SELECT * FROM categories")->fetchAll(PDO::FETCH_ASSOC); foreach ($data as $k => $v)< echo 'Category name: '.$v['name'].'
'; >PDO и оператор LIKE
Работая с подготовленными запросами, следует понимать, что плейсхолдер может заменять только строку или число. Ни ключевое слово, ни идентификатор, ни часть строки или набор строк через плейсхолдер подставить нельзя . Поэтому для LIKE необходимо сначала подготовить строку поиска целиком, а потом ее подставлять в запрос:
$search = 'комп'; $query = "SELECT * FROM categories WHERE `name` LIKE ?"; $params = ["%$search%"]; $stmt = $db->prepare($query); $stmt->execute($params); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); $i = 1; foreach ($data as $category)< echo $i++ . '. ' . $category['name'].'
'; >Здесь может вознинуть проблема! Поиск может не работать, потому как из базы у вас приходят данные в неправильной кодировке. Необходимо добавить кодировку в подключение, если она там не указана!
$db = new PDO('mysql:host=localhost;dbname=pdo;charset=utf8mb4', 'root', '');PDO и оператор LIMIT
Важно! Когда PDO работает в режиме эмуляции, все данные, которые были переданы напрямую в execute() , форматируются как строки. То есть, эскейпятся и обрамляются кавычками. Поэтому LIMIT . превращается в LIMIT '10', '10' и очевидным образом вызывает ошибку синтаксиса и, соответственно, пустой массив данных.
Решение #1 : Отключить режим эмуляции:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);Решение #2 : Биндить эти цифры через bindValue() , принудительно выставляя им тип PDO::PARAM_INT :
$limit = 3; $stm = $db->prepare('SELECT * FROM categories LIMIT ?'); $stm->bindValue(1, $limit, PDO::PARAM_INT); $stm->execute(); $data = $stm->fetchAll(); echo ''; print_r($data);
PDO и оператор IN
При выборке из таблицы необходимо доставать записи, соответствующие всем значениям массива.
$arr = [1,3,6]; $in = str_repeat('?,', count($arr) - 1) . '?'; $sql = "SELECT * FROM categories WHERE `id` IN ($in)"; $stm = $db->prepare($sql); $stm->execute($arr); $data = $stm->fetchAll(); echo ''; print_r($data);
Добавление записей
$name = 'Новая категория'; $query = "INSERT INTO `categories` (`name`) VALUES (:name)"; $params = [ ':name' => $name ]; $stmt = $pdo->prepare($query); $stmt->execute($params);Изменение записей
$id = 1; $name = 'Изменённая запись'; $query = "UPDATE `categories` SET `name` = :name WHERE `id` = :id"; $params = [ ':id' => $id, ':name' => $name ]; $stmt = $pdo->prepare($query); $stmt->execute($params);Удаление записей
$id = 1; $query = "DELETE FROM `categories` WHERE `id` = ?"; $params = [$id]; $stmt = $pdo->prepare($query); $stmt->execute($params);Использование транзакций
try < // Начало транзакции $pdo->beginTransaction(); // . code // Если в результате выполнения нашего кода всё прошло успешно, // то зафиксируем этот результат $pdo->commit(); > catch (Exception $e) < // Иначе, откатим транзакцию. $pdo->rollBack(); echo "Ошибка: " . $e->getMessage(); >Важно! Транзакции в PDO работают только с таблицами InnoDB
Мы познакомились с основными понятиями PDO, его установкой, подключением к БД и самые простые возможности выборки, изменения и удаления данных.
Класс PDO
Представляет соединение между PHP и сервером базы данных.
Обзор классов
class PDO < public const int PARAM_NULL ; public const int PARAM_BOOL = 5 ; public const int PARAM_INT = 1 ; public const int PARAM_STR = 2 ; public const int PARAM_LOB = 3 ; public const int PARAM_STMT = 4 ; public const int PARAM_INPUT_OUTPUT ; public const int PARAM_STR_NATL ; public const int PARAM_STR_CHAR ; public const int PARAM_EVT_ALLOC ; public const int PARAM_EVT_FREE ; public const int PARAM_EVT_EXEC_PRE ; public const int PARAM_EVT_EXEC_POST ; public const int PARAM_EVT_FETCH_PRE ; public const int PARAM_EVT_FETCH_POST ; public const int PARAM_EVT_NORMALIZE ; public const int FETCH_DEFAULT ; public const int FETCH_LAZY ; public const int FETCH_ASSOC ; public const int FETCH_NUM ; public const int FETCH_BOTH ; public const int FETCH_OBJ ; public const int FETCH_BOUND ; public const int FETCH_COLUMN ; public const int FETCH_CLASS ; public const int FETCH_INTO ; public const int FETCH_FUNC ; public const int FETCH_GROUP ; public const int FETCH_UNIQUE ; public const int FETCH_KEY_PAIR ; public const int FETCH_CLASSTYPE ; public const int FETCH_SERIALIZE ; public const int FETCH_PROPS_LATE ; public const int FETCH_NAMED ; public const int ATTR_AUTOCOMMIT ; public const int ATTR_PREFETCH ; public const int ATTR_TIMEOUT ; public const int ATTR_ERRMODE ; public const int ATTR_SERVER_VERSION ; public const int ATTR_CLIENT_VERSION ; public const int ATTR_SERVER_INFO ; public const int ATTR_CONNECTION_STATUS ; public const int ATTR_CASE ; public const int ATTR_CURSOR_NAME ; public const int ATTR_CURSOR ; public const int ATTR_ORACLE_NULLS ; public const int ATTR_PERSISTENT ; public const int ATTR_STATEMENT_CLASS ; public const int ATTR_FETCH_TABLE_NAMES ; public const int ATTR_FETCH_CATALOG_NAMES ; public const int ATTR_DRIVER_NAME ; public const int ATTR_STRINGIFY_FETCHES ; public const int ATTR_MAX_COLUMN_LEN ; public const int ATTR_EMULATE_PREPARES ; public const int ATTR_DEFAULT_FETCH_MODE ; public const int ATTR_DEFAULT_STR_PARAM ; public const int ERRMODE_SILENT ; public const int ERRMODE_WARNING ; public const int ERRMODE_EXCEPTION ; public const int CASE_NATURAL ; public const int CASE_LOWER ; public const int CASE_UPPER ; public const int NULL_NATURAL ; public const int NULL_EMPTY_STRING ; public const int NULL_TO_STRING ; public const string ERR_NONE ; public const int FETCH_ORI_NEXT ; public const int FETCH_ORI_PRIOR ; public const int FETCH_ORI_FIRST ; public const int FETCH_ORI_LAST ; public const int FETCH_ORI_ABS ; public const int FETCH_ORI_REL ; public const int CURSOR_FWDONLY ; public const int CURSOR_SCROLL ;
public __construct (
string $dsn ,
? string $username = null ,
? string $password = null ,
? array $options = null
)public beginTransaction (): bool
public commit (): bool
public errorCode (): ? string
public errorInfo (): array
public exec ( string $statement ): int | false
public getAttribute ( int $attribute ): mixed
public static getAvailableDrivers (): array
public inTransaction (): bool
public lastInsertId ( ? string $name = null ): string | false
public prepare ( string $query , array $options = [] ): PDOStatement | false
public query ( string $query , ? int $fetchMode = null ): PDOStatement | falsepublic query ( string $query , ? int $fetchMode = PDO::FETCH_COLUMN , int $colno ): PDOStatement | false
public query (
string $query ,
? int $fetchMode = PDO::FETCH_CLASS ,
string $classname ,
array $constructorArgs
): PDOStatement | falsepublic query ( string $query , ? int $fetchMode = PDO::FETCH_INTO , object $object ): PDOStatement | false
public quote ( string $string , int $type = PDO::PARAM_STR ): string | false
public rollBack (): bool
public setAttribute ( int $attribute , mixed $value ): boolUser Contributed Notes 8 notes
14 years ago
"And storing username/password inside class is not a very good idea for production code."
Good idea is to store database connection settings in *.ini files but you have to restrict access to them. For example this way:
my_setting.ini:
[database]
driver = mysql
host = localhost
;port = 3306
schema = db_schema
username = user
password = secretDatabase connection:
class MyPDO extends PDO
public function __construct ( $file = 'my_setting.ini' )
if (! $settings = parse_ini_file ( $file , TRUE )) throw new exception ( 'Unable to open ' . $file . '.' );$dns = $settings [ 'database' ][ 'driver' ] .
':host=' . $settings [ 'database' ][ 'host' ] .
((!empty( $settings [ 'database' ][ 'port' ])) ? ( ';port=' . $settings [ 'database' ][ 'port' ]) : '' ) .
';dbname=' . $settings [ 'database' ][ 'schema' ];parent :: __construct ( $dns , $settings [ 'database' ][ 'username' ], $settings [ 'database' ][ 'password' ]);
>
>
?>Database connection parameters are accessible via human readable ini file for those who screams even if they see one PHP/HTML/any_other command.
12 years ago
PDO and Dependency Injection
Dependency injection is good for testing. But for anyone wanting various data mapper objects to have a database connection, dependency injection can make other model code very messy because database objects have to be instantiated all over the place and given to the data mapper objects.
The code below is a good way to maintain dependency injection while keeping clean and minimal model code.
class DataMapper
public static $db ;public static function init ( $db )
self :: $db = $db ;
>
>class VendorMapper extends DataMapper
public static function add ( $vendor )
$st = self :: $db -> prepare (
"insert into vendors set
first_name = :first_name,
last_name = :last_name"
);
$st -> execute (array(
':first_name' => $vendor -> first_name ,
':last_name' => $vendor -> last_name
));
>
>// In your bootstrap
$db = new PDO (. );
DataMapper :: init ( $db );// In your model logic
$vendor = new Vendor ( 'John' , 'Doe' );
VendorMapper :: add ( $vendor );15 years ago
Keep in mind, you MUST NOT use 'root' user in your applications, unless your application designed to do a database maintenance.
And storing username/password inside class is not a very good idea for production code. You would need to edit the actual working code to change settings, which is bad.
6 years ago
I personnaly create a new instance of PDO like this :
$dbDatas = parse_ini_file( DB_FILE );
$dbOptions = [
\PDO::ATTR_DEFAULT_FECTH_MODE => \PDO::FETCH_OBJ,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION
];$dsn = sprintf( 'mysql:dbname=%s;host=%s', $dbDatas['dbname'],
$dbDatas['host'] );$this->cn = new \PDO( $dsn, $dbDatas['user'], $dbDatas['password'],
$dbOptions );
$this->cn->exec( 'SET CHARACTER SET UTF8' );10 years ago
Starting with PHP 5.4 you are unable to use persistent connections when you have your own database class derived from the native PDO class. If your code uses this combination, you will encounter segmentation faults during the cleanup of the PHP process.
You can still use _either_ a derived PDO class _or_ persistent connections.For more information, please see this bug report: https://bugs.php.net/bug.php?id=63176
5 years ago
For some Database Environment, such as Aliyun DRDS (Distributed Relational Database Service), cannot process preparing for SQL.
For such cases, the option `\PDO::ATTR_EMULATE_PREPARES` should be set to true. If you always got reports about "Failed to prepare SQL" while this option were set to false, you might try to turn on this option to emulate prepares for SQL.13 years ago
Here is an singleton PDO example:
[db_options]
PDO::MYSQL_ATTR_INIT_COMMAND=set names utf8private static function getLink ( ) if ( self :: $link ) return self :: $link ;
>$ini = _BASE_DIR . "config.ini" ;
$parse = parse_ini_file ( $ini , true ) ;$driver = $parse [ "db_driver" ] ;
$dsn = " $ < driver >:" ;
$user = $parse [ "db_user" ] ;
$password = $parse [ "db_password" ] ;
$options = $parse [ "db_options" ] ;
$attributes = $parse [ "db_attributes" ] ;self :: $link = new PDO ( $dsn , $user , $password , $options ) ;
foreach ( $attributes as $k => $v ) self :: $link -> setAttribute ( constant ( "PDO:: < $k >" )
, constant ( "PDO:: < $v >" ) ) ;
>return self :: $link ;
>public static function __callStatic ( $name , $args ) $callback = array ( self :: getLink ( ), $name ) ;
return call_user_func_array ( $callback , $args ) ;
>
> ?>$stmt = Database :: prepare ( "SELECT 'something' ;" ) ;
$stmt -> execute ( ) ;
var_dump ( $stmt -> fetchAll ( ) ) ;
$stmt -> closeCursor ( ) ;
?>5 years ago
1) Do not use your ddbb info in the same file
2) DO NOT NEVER USE "All privileges user" for everything, always create an alternative user with restricted permissions (basic: SELECT, INSERT and so on)
- PDO
- Введение
- Установка и настройка
- Предопределённые константы
- Подключения и управление подключениями
- Транзакции и автоматическая фиксация изменений
- Подготовленные запросы и хранимые процедуры
- Ошибки и их обработка
- Большие объекты (LOB)
- PDO
- PDOStatement
- PDOException
- Драйверы PDO
- Copyright © 2001-2023 The PHP Group
- My PHP.net
- Contact
- Other PHP.net sites
- Privacy policy
Функции MySQL (PDO_MYSQL)
PDO_MYSQL - это драйвер, реализующий интерфейс PHP Data Objects (PDO) и предоставляет доступ из PHP к базам данных MySQL.
PDO_MYSQL по умолчанию использует эмулированную подготовку.
MySQL 8
При запуске PHP до версии 7.1.16 или PHP 7.2 до 7.2.4, установите плагин пароля по умолчанию MySQL 8 Server в 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). Вместо этого измените это, установив default_authentication_plugin=mysql_native_password в my.cnf . Плагин caching_sha2_password будет поддерживаться в будущей версии 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::getAttribute() для получения атрибута PDO::ATTR_DRIVER_NAME для проверки драйвера.
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY ( bool ) По умолчанию все запросы выполняются в буферизованном режиме. Если этот атрибут установлен в значение false для объекта PDO , драйвер MySQL будет использовать небуферизованный режим.
Пример #1 Установка небуферизованного режима MySQL
$pdo = new PDO ( "mysql:host=localhost;dbname=world" , 'my_user' , 'my_password' );
$pdo -> setAttribute ( PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY , false );?php
$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-сертификата сервера.
Существует, начиная с 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" PHP_INI_SYSTEM pdo_mysql.debug NULL PHP_INI_SYSTEM Для подробного описания констант PHP_INI_*, обратитесь к разделу Где могут быть установлены параметры конфигурации.
Краткое разъяснение конфигурационных директив.
Устанавливает сокет домена UNIX. Эту опцию необходимо указать во время компиляции, если сокет домена найден во время конфигурирования. Эта настройка только для Unix.
Разрешает отладку для PDO_MYSQL. Эта настройка доступна только, если PDO_MYSQL скомпилирован с "mysqlnd" и в режиме отладки PDO.
User Contributed Notes 8 notes
5 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)possible values: true, false
default value: true15 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.
16 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()
12 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:
$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'
)
);
?>15 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 )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() . "
";
die();
>
?>15 years ago
SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. .
This one can be a royal pain to deal with. Never stack statements to be executed in one go. Nobody ever mentions this possibility in all the posts I've seen dealing with this error.
This example is a Zend Framework example but the theory is the same.
$sql = CREATE TABLE IF NOT EXISTS `ticket_hist` (
`tid` int(11) NOT NULL,
`trqform` varchar(40) NOT NULL,
`trsform` varchar(40) NOT NULL,
`tgen` datetime NOT NULL,
`tterm` datetime,
`tstatus` tinyint(1) NOT NULL
) ENGINE=ARCHIVE COMMENT='ticket archive';
CREATE TABLE IF NOT EXISTS `request_hist` (
`rqid` int(11) NOT NULL,
`rqtid` int(11) NOT NULL,
`rqsid` int(11) NOT NULL,
`rqdate` datetime NOT NULL,
`rqcode` tinyint(1) NOT NULL,
`rssid` int(11) NOT NULL,
`rsdate` datetime,
`rscode` tinyint(1)
) ENGINE=ARCHIVE COMMENT='request archive';
CREATE TABLE IF NOT EXISTS `relay_hist` (
`rqid` int(5) NOT NULL,
`sdesc` varchar(40) NOT NULL,
`rqemail` varchar(40) NOT NULL,
`sid` int(11) NOT NULL,
`rlsid` int(11) NOT NULL,
`dcode` varchar(5) NOT NULL
) ENGINE=ARCHIVE COMMENT='relay archive';
____SQL;
$result = $this -> db -> getConnection ()-> exec ( $sql );
?>This will run fine but PDO will balk with the 'unbuffered' error if you follow this with another query.
$sql = CREATE TABLE IF NOT EXISTS `ticket_hist` (
`tid` int(11) NOT NULL,
`trqform` varchar(40) NOT NULL,
`trsform` varchar(40) NOT NULL,
`tgen` datetime NOT NULL,
`tterm` datetime,
`tstatus` tinyint(1) NOT NULL
) ENGINE=ARCHIVE COMMENT='ticket archive';
____SQL;
$result = $this -> db -> getConnection ()-> exec ( $sql );$sql = CREATE TABLE IF NOT EXISTS `request_hist` (
`rqid` int(11) NOT NULL,
`rqtid` int(11) NOT NULL,
`rqsid` int(11) NOT NULL,
`rqdate` datetime NOT NULL,
`rqcode` tinyint(1) NOT NULL,
`rssid` int(11) NOT NULL,
`rsdate` datetime,
`rscode` tinyint(1)
) ENGINE=ARCHIVE COMMENT='request archive';
____SQL;
$result = $this -> db -> getConnection ()-> exec ( $sql );$sql = CREATE TABLE IF NOT EXISTS `relay_hist` (
`rqid` int(5) NOT NULL,
`sdesc` varchar(40) NOT NULL,
`rqemail` varchar(40) NOT NULL,
`sid` int(11) NOT NULL,
`rlsid` int(11) NOT NULL,
`dcode` varchar(5) NOT NULL
) ENGINE=ARCHIVE COMMENT='relay archive';
____SQL;
$result = $this -> db -> getConnection ()-> exec ( $sql );
?>Chopping it into individual queries fixes the problem.
6 years ago
If you have the error 'could not find driver' and won't able to install driver for newer linux(Fedora, Redhat, CentOS) with latest PHP7/MariaDB10/Apache2.4 get this package installed and get every things smooth.
First download latest version of epel and remi for your distribution. This links is for Fedora 26:Than install them
rpm -Uvh remi-release-26.rpm
rpm -Uvh epel-release-6-8.noarch.rpmKnow you can use remi repository to gest php-pdo and php-mysql.
yum --enablerepo=remi install php-pdo
yum --enablerepo=remi install php-mysqlRestart the Apache
systemctl stop httpd
systemctl start httpd10 years ago
This page suggests that the constant PDO::MYSQL_ATTR_FOUND_ROWS was always available (no note "exists as of X.X"), but I found the constant missing on an installation with PHP 5.2. After switching the PHP version to 5.3.27 on the webspace the constant was available.
- Драйверы PDO
- CUBRID (PDO)
- MS SQL Server (PDO_DBLIB)
- Firebird (PDO)
- IBM (PDO)
- Informix (PDO)
- MySQL (PDO)
- MS SQL Server (PDO)
- Oracle (PDO)
- ODBC и DB2 (PDO)
- PostgreSQL (PDO)
- SQLite (PDO)
- Copyright © 2001-2023 The PHP Group
- My PHP.net
- Contact
- Other PHP.net sites
- Privacy policy
