sunsey
@sunsey
Web dev

PDO — полный отладочный запрос?

Вопрос к людям, постоянно использующим PDO.

Планирую перейти на PDO, но очень смущает невозможность простым способом просмотреть финальный запрос, отправляемый в БД с уже подставленными параметрами (:id :name). Очень удобно при отладке например в ПМА. Некоторые изобретают такие велосипеды stackoverflow.com/a/1376838/1101589. Вы как то это решаете или для вас это не актуально, возможно делаете отладку по другому? Знаю, что серверные prepared statements работают по другому, но я их особо и не планирую использовать.
  • Вопрос задан
  • 15296 просмотров
Решения вопроса 1
AlexTest
@AlexTest
Исходя из логики работы PDO c БД — для нормальной отладки таки придется писать свой велосипед, т.к. сначала хочется полную строку запроса посмотреть, потом узнать где был вызван запрос, сколько он выполнялся и т.д. и т.п.
Самый правильный способ — отнаследоваться от PDO и PDOStatement, а своей обертке уже сделать «блекджек со шлюхами» например как здесь daveyshafik.com/archives/605-debugging-pdo-prepared-statements.html
По ссылке выше далеко не самое лучшее решение, я бы перекрыл метод execute в PDOStatement и другие подобные методы так, чтобы например при включенной опции отладки они сами бы складывали нужную мне информацию в нужное место, а при выключенной отладке просто сквозняком пропускали запросы к PDO.
Ответ написан
Пригласить эксперта
Ответы на вопрос 6
Stdit
@Stdit
Я на дев-машине обычно включаю логгинг всех запросов средствами SQL-сервера, и смотрю что там происходит.

Вот пример (MySQL):
$st = $pdo->prepare('SELECT * FROM user WHERE id=:id');
$id = 2;
$st->bindParam(':id', $id, PDO::PARAM_INT);
$st->execute();
$r = $st->fetchAll();
Выдаёт в MySQL-лог строчку
 6 Query	SELECT * FROM user WHERE id=2

При использовании PostgreSQL выглядит это несколько по-другому:
LOG:  duration: 2.669 ms  parse pdo_stmt_00000af1: SELECT * FROM "item" LIMIT $1 OFFSET $2
LOG:  duration: 0.126 ms  bind pdo_stmt_00000af1: SELECT * FROM "item" LIMIT $1 OFFSET $2
DETAIL:  parameters: $1 = '20', $2 = '0'
LOG:  duration: 0.118 ms  execute pdo_stmt_00000af1: SELECT * FROM "item" LIMIT $1 OFFSET $2
DETAIL:  parameters: $1 = '20', $2 = '0'
LOG:  duration: 0.172 ms  statement: DEALLOCATE pdo_stmt_00000af1

При желании можно SQL-лог направить в тот же файл, что и дебаговый PHP-лог, чтобы не переключаться между окнами терминалов с «tail -f», которые следят за логами.
Ответ написан
FanatPHP
@FanatPHP
Чебуратор тега РНР
Если не планируется использовать серверные плейсхолдеры, то тогда я вообще не вижу смысла использовать встроенный парсер ПДО.
Пишем свой и имеем
а) кучу дополнительных плейсхолдеров
б) возможность подставлять плейсхолдер в кусок запроса, а не только в целый
в) отладочный вывод.
Ответ написан
zoc
@zoc
Такой же вопрос, как у вас, решение немного костыльное но работает:
stackoverflow.com/questions/7716785/get-last-executed-query-in-php-pdo
Ответ написан
ohmytribe
@ohmytribe
У меня не конкретно ответ на поставленный вопрос, но просто чтобы было понятнее, почему это работает так. PDO использует параметризованные запросы, это значит, что в БД запрос сохраняется именно как
SELECT *
FROM `table`
WHERE `id` = :id

при следующем вызове этого запроса, но с другими параметрами, движок базы данных уже не будет компилировать этот запрос, просто выполнит его с новыми параметрами. Можно сказать, что это подобие хранимых процедур.
Ответ написан
lumega
@lumega
можно горы городить в своем коде для отладки SQL, но зачем это? ведь наша задача сводится по сути к тому, чтобы выявить кто именно приходит к конечному Mysql серверу. Для этого есть тулза Neor Profile SQL.
И разницы нет что мониторить: PDO или обычные конструкции.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы