У меня есть модуль, который плохо себя ведет. EFQ возвращает неожиданные результаты, но я не могу понять почему, просто взглянув на код. Есть ли эквивалент dpq () для EFQ? Другие способы их отладки?
Аналогичный вопрос: drupal.stackexchange.com/questions/33473/… . Можете ли вы привести объект запроса к строке, чтобы проверить его, чтобы увидеть, дает ли SQL какие-либо подсказки?
Клайв
1
Хорошие предложения, однако: Восстанавливаемая фатальная ошибка: Объект класса EntityFieldQuery не может быть преобразован в строку :(
Летарион,
Ответы:
36
Это немного хак, но вы можете добавить тег к любому, для которого EntityFieldQueryвы хотите напечатать запрос, затем реализовать его hook_query_alter()для перехвата, когда это стандарт SelectQuery, а затем преобразовать его в строку для отладки:
function MYMODULE_query_alter($query){if($query->hasTag('efq_debug')){
dpm((string)$query);}}
$q =newEntityFieldQuery;
$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 в качестве системы хранения на местах.
Звучит здорово в теории, но как насчет комментариев по этому вопросу? EFQ не реализует __toString ()?
Летарион
4
К тому времени, когда он попадает hook_query_alter()в запрос, его уже нет EntityFieldQuery, он был преобразован в стандарт db_select(), поэтому __tostring()отлично работает :) С тех пор, как я его разработал, я довольно часто его использую, и он работает довольно хорошо
Clive
Подтвердил, что приведение к строке работает, как только запрос попадает в hook_query_alter().
Jhedstrom
Чтобы увидеть аргументы запроса («: entity_type» в приведенном выше примере), вы можете использовать dpm ($ query-> arguments ());
Санзанте
13
Вместо того , чтобы добавить собственные hook_query_alter () вы можете позволить Devel модулю делать тяжелую работу за вас, добавив debugтег:
Добавление к ответу @Clive, который обычно печатает запрос с заполнителем, а не со значением. Чтобы напечатать значение с запросом, используйте следующий код под hook_query_alter.
хороший альтернативный обходной путь для разработки. Не удалось найти этот модуль непосредственно над DO, потому что они удалили связанный блок модуля, который был там раньше.
Киранкинг
1
Вы можете попробовать отладить его через XDebug . После установки выполните xdebug_start_trace()перед кодом и xdebug_stop_trace()после этого у вас будет четкий журнал трассировки, что было выполнено и где.
Также вы можете включить регистратор запросов в конфигурации MySQL.
Другой метод - использовать strace / truss / dtruss как отладчики.
Обратите внимание, что dtrussэто всего лишь сценарий, использующий DTrace, поэтому вы можете рассмотреть прямую реализацию статических пробников PHP DTrace или DTracing MySQL , написав свой собственный сценарий.
Добавьте эту функцию в ваш модуль. Затем добавьте тег 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);}}
Ответы:
Это немного хак, но вы можете добавить тег к любому, для которого
EntityFieldQuery
вы хотите напечатать запрос, затем реализовать егоhook_query_alter()
для перехвата, когда это стандартSelectQuery
, а затем преобразовать его в строку для отладки:Это немного взломать, но делает свое дело. Выход для вышеупомянутого:
Предположительно, это также будет работать только при использовании MySQL в качестве системы хранения на местах.
источник
hook_query_alter()
в запрос, его уже нетEntityFieldQuery
, он был преобразован в стандартdb_select()
, поэтому__tostring()
отлично работает :) С тех пор, как я его разработал, я довольно часто его использую, и он работает довольно хорошоhook_query_alter()
.Вместо того , чтобы добавить собственные hook_query_alter () вы можете позволить Devel модулю делать тяжелую работу за вас, добавив
debug
тег:Это выведет запрос на экран, как если
dpq()
быисточник
Добавление к ответу @Clive, который обычно печатает запрос с заполнителем, а не со значением. Чтобы напечатать значение с запросом, используйте следующий код под hook_query_alter.
Не рекомендуется устанавливать модуль для нескольких строк кода. Вот почему я выбрал вышеупомянутое решение.
источник
Если вы загрузите dev-версию Nice DPQ (или что-то еще => 1.1), вы можете просто сделать:
и вы получите запрос dpm'ed приятно :). Важной частью кода выше является addTag ('nicedpq'), который запускает
dpm()
.источник
Вы можете попробовать отладить его через XDebug . После установки выполните
xdebug_start_trace()
перед кодом иxdebug_stop_trace()
после этого у вас будет четкий журнал трассировки, что было выполнено и где.Также вы можете включить регистратор запросов в конфигурации MySQL.
Другой метод - использовать strace / truss / dtruss как отладчики.
Пример использования dtruss:
все запросы
конкретные запросы
Обратите внимание, что
dtruss
это всего лишь сценарий, использующий DTrace, поэтому вы можете рассмотреть прямую реализацию статических пробников PHP DTrace или DTracing MySQL , написав свой собственный сценарий.Подробнее: Расширенная отладка ядра Drupal с помощью командной строки (strace & tcpdump)
источник
Добавьте эту функцию в ваш модуль. Затем добавьте тег
debug
к любому EFQ. Требуется модуль Devel, чтобы распечатать запрос.источник