Mam moduł, który źle działa. EFQ jest returing nieoczekiwane rezultaty, ale nie widzę , dlaczego po prostu patrząc na kod. Czy istnieje odpowiednik dpq () dla EFQ? Inne sposoby ich debugowania?
Mam moduł, który źle działa. EFQ jest returing nieoczekiwane rezultaty, ale nie widzę , dlaczego po prostu patrząc na kod. Czy istnieje odpowiednik dpq () dla EFQ? Inne sposoby ich debugowania?
Odpowiedzi:
To trochę hack, ale możesz dodać tag do każdego, EntityFieldQuery
kto jest zainteresowany wydrukowaniem zapytania, a następnie zaimplementować hook_query_alter()
przechwytywanie, gdy jest to standard SelectQuery
, a następnie rzucić go na ciąg znaków w celu debugowania:
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();
To trochę hack, ale załatwia sprawę. Wynik dla powyższego jest:
SELECT node.nid AS entity_id, node.vid AS revision_id, node.type AS bundle, :entity_type
AS entity_type
FROM {node} node
Przypuszczalnie zadziała to również tylko przy użyciu MySQL jako systemu pamięci masowej.
hook_query_alter()
zapytania, już nie jest EntityFieldQuery
, zostało przekonwertowane do standardu db_select()
, więc __tostring()
działa świetnie :) Odkąd to wypracowałem, używałem go całkiem sporo i działa całkiem dobrze
hook_query_alter()
.
Zamiast tworzyć własną funkcję hook_query_alter (), możesz pozwolić modułowi Devel wykonać ciężkie podnoszenie, dodając debug
tag:
$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node');
->addTag('debug')
->execute();
Spowoduje to wydrukowanie zapytania na ekranie, tak jak dpq()
by to zrobiło.
Dodanie do odpowiedzi @Clive, która generalnie drukuje zapytanie z symbolem zastępczym nie razem z wartością. Aby wydrukować wartość z zapytaniem, użyj następującego kodu pod 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();
Nie jest dobrą praktyką instalowanie modułu dla kilku wierszy kodu. Dlatego zdecydowałem się na wyżej wspomniane rozwiązanie.
Jeśli pobierzesz wersję deweloperską Nice DPQ (lub cokolwiek => 1.1), możesz po prostu zrobić:
$user_query = new EntityFieldQuery();
$user_query->entityCondition('entity_type','user');
$user_query->addTag('nicedpq');
$user_result = $user_query->execute();
i dostaniesz ładnie dpm'owane zapytanie :). Ważną częścią powyższego kodu jest addTag ('nicedpq') - który uruchamia dpm()
.
Możesz spróbować debugować go za pomocą XDebug . Po zainstalowaniu wykonaj xdebug_start_trace()
przed kodem, a xdebug_stop_trace()
następnie wyczyść dziennik śledzenia, co zostało wykonane i gdzie.
Możesz także włączyć rejestrator zapytań w konfiguracji MySQL.
Inną metodą jest użycie strace / truss / dtruss jak debuggerów.
Przykład użycia dtruss:
wszystkie zapytania
sudo dtruss -t read -n mysqld
konkretne zapytania
sudo dtruss -t read -n mysqld 2>&1 | grep SPECIFIC_TEXT
Zauważ, że dtruss
to tylko skrypt, który używa DTrace, więc możesz rozważyć bezpośrednią implementację statycznych sond PHP DTrace lub DTracing MySQL , pisząc własny skrypt.
Czytaj więcej: Zaawansowane debugowanie rdzenia Drupala za pomocą wiersza poleceń (strace i tcpdump)
Dodaj tę funkcję do swojego modułu. Następnie dodaj znacznik debug
do dowolnego EFQ. Wymaga włączenia modułu Devel w celu wydrukowania zapytania.
/**
* 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);
}
}