EntityFieldQuery debuggen?

27

Ich habe ein Modul, das sich schlecht benimmt. Ein EFQ liefert unerwartete Ergebnisse, aber ich kann nicht erkennen, warum dies so ist, wenn ich nur den Code betrachte. Gibt es ein dpq () -Äquivalent für EFQs? Andere Möglichkeiten zum Debuggen?

Letharion
quelle
Ähnliche Frage: drupal.stackexchange.com/questions/33473/… . Können Sie das Abfrageobjekt in eine Zeichenfolge umwandeln, um festzustellen, ob die SQL Hinweise gibt?
Clive
1
Tolle Vorschläge: Behebbarer schwerwiegender Fehler: Objekt der Klasse EntityFieldQuery konnte nicht in Zeichenfolge konvertiert werden :(
Letharion

Antworten:

36

Es ist ein kleiner Hack, aber Sie können jedem EntityFieldQuery, der die Abfrage drucken möchte, ein Tag hinzufügen und dann implementieren hook_query_alter(), um sie abzufangen, wenn es sich um einen Standard handelt SelectQuery, und sie dann zum Debuggen in einen String umwandeln:

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();

Es ist ein bisschen hacken, aber macht den Trick. Die Ausgabe für das Obige ist:

SELECT node.nid AS entity_id, node.vid AS revision_id, node.type AS bundle, :entity_type     
AS entity_type
FROM {node} node

Vermutlich funktioniert dies auch nur, wenn MySQL als Feldspeichersystem verwendet wird.

Clive
quelle
Hört sich theoretisch gut an, aber was ist mit den Kommentaren zu der Frage? EFQ implementiert __toString () nicht?
Letharion
4
Mit der Zeit wird es auf hook_query_alter()die Abfrage nicht eine ist EntityFieldQuerynicht mehr, es ist zu einem Standard umgewandelt worden nach unten db_select(), so __tostring()funktioniert gut :) Da diese Arbeit aus Ich habe es ziemlich viel verwenden und es funktioniert ziemlich gut
Clive
Bestätigt, dass das Umwandeln in eine Zeichenfolge funktioniert, sobald die Abfrage ausgeführt wird hook_query_alter().
JHEDSTROM
Um die Abfrageargumente (": entity_type" im obigen Beispiel) anzuzeigen, können Sie dpm ($ query-> arguments ()) verwenden.
sanzante
13

Anstatt Ihren eigenen hook_query_alter () zu rollen, können Sie das Devel- Modul das schwere Heben für Sie erledigen lassen, indem Sie das debugTag hinzufügen :

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

Dadurch wird die Abfrage wie gewohnt auf dem Bildschirm dpq()ausgedruckt.

Dalin
quelle
4

Hinzufügen zur @Clive-Antwort, bei der die Abfrage in der Regel mit dem Platzhalter und nicht mit dem Wert gedruckt wird. Verwenden Sie den folgenden Code unter dem Hook_query_alter, um den Wert mit der Abfrage zu drucken.

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();

Es wird nicht empfohlen, ein Modul für die wenigen Codezeilen zu installieren. Deshalb habe ich mich für die oben genannte Lösung entschieden.

Sukhjinder Singh
quelle
2

Wenn Sie die Entwicklerversion von Nice DPQ (oder etwas anderes => 1.1) herunterladen , können Sie einfach Folgendes tun:

$user_query = new EntityFieldQuery();
$user_query->entityCondition('entity_type','user');
$user_query->addTag('nicedpq');
$user_result = $user_query->execute();

und du wirst die frage dpm'ed schön bekommen :). Der wichtige Teil im obigen Code ist addTag ('nicedpq') - das löst das aus dpm().

mojzis
quelle
schöne alternative Problemumgehung zu entwickeln. Das Modul konnte nicht direkt über DO gefunden werden, da der zugehörige Modulblock entfernt wurde, der bereits vorhanden war.
kiranking
1

Sie können versuchen, es über XDebug zu debuggen . Führen Sie nach der Installation xdebug_start_trace()vor dem Code und xdebug_stop_trace()danach ein eindeutiges Ablaufverfolgungsprotokoll aus, was und wo ausgeführt wurde.

Sie können auch den Abfrage-Logger in der MySQL-Konfiguration aktivieren.

Die andere Methode ist, strace / truss / dtruss wie Debugger zu verwenden.

Beispiel mit dtruss:

  • alle Abfragen

    sudo dtruss -t read -n mysqld
  • spezifische Abfragen

    sudo dtruss -t read -n mysqld 2>&1 | grep SPECIFIC_TEXT

Beachten Sie, dass dies dtrussnur ein Skript ist, das DTrace verwendet. Sie können also eine direkte Implementierung von statischen PHP DTrace- Tests oder DTracing MySQL in Betracht ziehen, indem Sie Ihr eigenes Skript schreiben.

Weiterlesen : Erweitertes Debuggen von Drupal-Core über die Kommandozeile (strace & tcpdump)

Kenorb
quelle
0

Fügen Sie diese Funktion Ihrem Modul hinzu. debugFügen Sie dann das Tag einem beliebigen EFQ hinzu. Erfordert die Aktivierung des Entwicklungsmoduls, um die Abfrage drucken zu können.

/**
 * 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
quelle