Страницы

Поиск по вопросам

пятница, 11 января 2019 г.

PHP PDO в чем разница ATTR_EMULATE_PREPARES, false и true

Пробовал вставлять значения разных типов данных в колонки с разными типами данных при ATTR_EMULATE_PREPARES, false и true, разницы не увидел, может кто объяснить в чем отличие?
//типы колонов r1 = int, r2 = varchar, r3 = bool
$pdo = new PDO('mysql:host=localhost;dbname=test;charser=utf8', 'root', ''); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$smt = $pdo->prepare('INSERT INTO pwnd (r1, r2 ,r3) VALUES (:r1, :r2, :r3)'); echo $smt->execute([':r1' => 'a2', ':r3' => 'false', ':r2' => true]);


Ответ

С PDO::ATTR_EMULATE_PREPARES в значении true за обработку подготовленных выражений отвечает сам PDO. В базу данных передаётся чистый запрос с уже подставленными и корректно экранированными данными (только в dsn не забывайте правильно charset указывать).
PDO::ATTR_EMULATE_PREPARES в значении false именно использует штатный механизм СУБД для подготовки запроса и затем отдельным обращением передаёт данные для этого запроса. Т.е. нормальные, реальные подготовленные выражения.
Из не очевидных моментов:
для сложных запросов дико удобно использовать именованные параметры несколько раз. Какой-нибудь where user_from = :id or user_to = :id и передать только один id. Такое возможно только с эмуляцией запросов. специфика конкретных СУБД. Какие-то СУБД из тех, что умеет PDO могут не уметь подготовленные выражения. Например, очень популярный PgBouncer (пул коннектов для PostgreSQL) не умеет обрабатывать подготовленные выражения. С эмуляцией выражений можно в коде проекта пользоваться удобствами API с prepare вопрос с тем, что подготовленный запрос разбирается и строит план один раз и затем только выполняется - на самом деле гораздо сложнее. Тот же mysql сохраняет запрос только в рамках соединения. Поэтому в типичном сценарии использования "подготовил, выполнил, закрыл соединение" никаких плюсов реальное препарирование не даёт. А кэширование плана между соединениями - по-моему (сам с этой СУБД не работал), есть в Oracle и приносит некоторое количество головной боли, ведь оптимальный план запроса в немалой степени зависит от самих данных.

Комментариев нет:

Отправить комментарий