Отладка EntityFieldQuery?

27

У меня есть модуль, который плохо себя ведет. EFQ возвращает неожиданные результаты, но я не могу понять почему, просто взглянув на код. Есть ли эквивалент dpq () для EFQ? Другие способы их отладки?

Letharion
источник
Аналогичный вопрос: 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 = 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 в качестве системы хранения на местах.

Клайв
источник
Звучит здорово в теории, но как насчет комментариев по этому вопросу? 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тег:

$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node');
  ->addTag('debug')
  ->execute();

Это выведет запрос на экран, как если dpq()бы

Далин
источник
4

Добавление к ответу @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();

Не рекомендуется устанавливать модуль для нескольких строк кода. Вот почему я выбрал вышеупомянутое решение.

Сукхиндер Сингх
источник
2

Если вы загрузите 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().

mojzis
источник
хороший альтернативный обходной путь для разработки. Не удалось найти этот модуль непосредственно над DO, потому что они удалили связанный блок модуля, который был там раньше.
Киранкинг
1

Вы можете попробовать отладить его через 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)

kenorb
источник
0

Добавьте эту функцию в ваш модуль. Затем добавьте тег 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);
  }
}
KeyboardCowboy
источник