web-dev-qa-db-fra.com

Déboguer EntityFieldQuery?

J'ai un module qui se comporte mal. Un EFQ retient des résultats inattendus, mais je ne vois pas pourquoi juste en regardant le code. Existe-t-il un dpq () équivalent pour les EFQ? D'autres façons de les déboguer?

26
Letharion

C'est un tout petit hack, mais vous pouvez ajouter une balise à n'importe quel EntityFieldQuery pour lequel vous souhaitez imprimer la requête, puis implémenter hook_query_alter() pour intercepter quand il s'agit d'un SelectQuery standard, puis convertissez-le en chaîne pour le débogage:

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

C'est un peu un hack mais ça fait l'affaire. La sortie de ce qui précède est:

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

Vraisemblablement, cela ne fonctionnera que lors de l'utilisation de MySQL comme système de stockage sur le terrain.

36
Clive

Plutôt que de lancer votre propre hook_query_alter (), vous pouvez laisser le module Devel faire le gros du travail pour vous en ajoutant la balise debug:

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

Cela affichera la requête à l'écran, comme le ferait dpq().

13
Dalin

Ajout à la réponse @Clive, qui imprime généralement la requête avec l'espace réservé et non avec la valeur. Pour imprimer la valeur avec la requête, utilisez le code suivant sous 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();

Il n'est pas recommandé d'installer un module pour les quelques lignes de code. C'est pourquoi j'ai opté pour la solution susmentionnée.

4
Sukhjinder Singh

Si vous téléchargez la version dev de Nice DPQ (ou n'importe quoi => 1.1), vous pouvez simplement faire:

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

et vous obtiendrez la requête dpm'ed bien :). La partie importante dans le code ci-dessus est addTag ('nicedpq') - qui déclenche la dpm().

2
mojzis

Vous pouvez essayer de le déboguer via XDebug . Une fois installé, faites xdebug_start_trace() avant le code, et xdebug_stop_trace() après cela, alors vous aurez un journal de trace clair ce qui a été exécuté et où.

Vous pouvez également activer l'enregistreur de requêtes dans la configuration MySQL.

L'autre méthode consiste à utiliser strace/truss/dtruss comme des débogueurs.

Exemple utilisant dtruss:

  • toutes les requêtes

    Sudo dtruss -t read -n mysqld
    
  • requêtes spécifiques

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

Notez que dtruss est juste un script qui utilise DTrace, vous pouvez donc considérer une implémentation directe de PHP DTrace static probes ou DTracing MySQL en écrivant votre propre script .

En savoir plus: Débogage avancé de Drupal core en utilisant la ligne de commande (strace & tcpdump)

1
kenorb

Ajoutez cette fonction à votre module. Ensuite, ajoutez la balise debug à n'importe quel EFQ. Nécessite que le module Devel soit activé pour imprimer la requête.

/**
 * 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);
  }
}
0
KeyboardCowboy