У меня есть модуль, который плохо себя ведет. EFQ возвращает неожиданные результаты, но я не могу понять почему, просто взглянув на код. Есть ли эквивалент dpq () для EFQ? Другие способы их отладки?
У меня есть модуль, который плохо себя ведет. EFQ возвращает неожиданные результаты, но я не могу понять почему, просто взглянув на код. Есть ли эквивалент dpq () для EFQ? Другие способы их отладки?
Ответы:
Это немного хак, но вы можете добавить тег к любому, для которого EntityFieldQuery
вы хотите напечатать запрос, затем реализовать его hook_query_alter()
для перехвата, когда это стандарт SelectQuery
, а затем преобразовать его в строку для отладки:
function MYMODULE_query_alter($query) {
if ($query->hasTag('efq_debug')) {
dpm((string)$query);
}
}
$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node')
->addTag('efq_debug')
->execute();
Это немного взломать, но делает свое дело. Выход для вышеупомянутого:
SELECT node.nid AS entity_id, node.vid AS revision_id, node.type AS bundle, :entity_type
AS entity_type
FROM {node} node
Предположительно, это также будет работать только при использовании MySQL в качестве системы хранения на местах.
hook_query_alter()
в запрос, его уже нет EntityFieldQuery
, он был преобразован в стандарт db_select()
, поэтому __tostring()
отлично работает :) С тех пор, как я его разработал, я довольно часто его использую, и он работает довольно хорошо
hook_query_alter()
.
Вместо того , чтобы добавить собственные hook_query_alter () вы можете позволить Devel модулю делать тяжелую работу за вас, добавив debug
тег:
$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node');
->addTag('debug')
->execute();
Это выведет запрос на экран, как если dpq()
бы
Добавление к ответу @Clive, который обычно печатает запрос с заполнителем, а не со значением. Чтобы напечатать значение с запросом, используйте следующий код под hook_query_alter.
function hook_query_alter($query) {
if ($query->hasTag('debug')) {
$sql = (string)$query;
$connection = Database::getConnection();
foreach ((array) $query->arguments() as $key => $val) {
$quoted[$key] = $connection->quote($val);
}
$sql = strtr($sql, $quoted);
dpm($sql);
}
}
$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node');
->addTag('debug');
->execute();
Не рекомендуется устанавливать модуль для нескольких строк кода. Вот почему я выбрал вышеупомянутое решение.
Если вы загрузите dev-версию Nice DPQ (или что-то еще => 1.1), вы можете просто сделать:
$user_query = new EntityFieldQuery();
$user_query->entityCondition('entity_type','user');
$user_query->addTag('nicedpq');
$user_result = $user_query->execute();
и вы получите запрос dpm'ed приятно :). Важной частью кода выше является addTag ('nicedpq'), который запускает dpm()
.
Вы можете попробовать отладить его через XDebug . После установки выполните xdebug_start_trace()
перед кодом и xdebug_stop_trace()
после этого у вас будет четкий журнал трассировки, что было выполнено и где.
Также вы можете включить регистратор запросов в конфигурации MySQL.
Другой метод - использовать strace / truss / dtruss как отладчики.
Пример использования dtruss:
все запросы
sudo dtruss -t read -n mysqld
конкретные запросы
sudo dtruss -t read -n mysqld 2>&1 | grep SPECIFIC_TEXT
Обратите внимание, что dtruss
это всего лишь сценарий, использующий DTrace, поэтому вы можете рассмотреть прямую реализацию статических пробников PHP DTrace или DTracing MySQL , написав свой собственный сценарий.
Подробнее: Расширенная отладка ядра Drupal с помощью командной строки (strace & tcpdump)
Добавьте эту функцию в ваш модуль. Затем добавьте тег debug
к любому EFQ. Требуется модуль Devel, чтобы распечатать запрос.
/**
* Implements hook_query_TAG_alter().
*
* Add the tag 'debug' to any EFQ and this will print the query to the messages.
*
* @param \QueryAlterableInterface $query
*/
function MYMODULE_query_debug_alter(QueryAlterableInterface $query) {
if (function_exists('dpq') && !$query->hasTag('debug-semaphore')) {
$query->addTag('debug-semaphore');
dpq($query);
}
}