J'ai un module qui se comporte mal. Un EFQ retient des résultats inattendus, mais je ne vois pas pourquoi simplement en regardant le code. Existe-t-il un équivalent dpq () pour les EFQ? D'autres façons de les déboguer?
Question similaire: drupal.stackexchange.com/questions/33473/… . Pouvez-vous convertir l'objet de requête en une chaîne pour l'inspecter pour voir si le SQL donne des indices?
Clive
1
Excellentes suggestions, cependant: erreur fatale récupérable: l'objet de la classe EntityFieldQuery n'a pas pu être converti en chaîne :(
Letharion
Réponses:
36
C'est un peu un hack, mais vous pouvez ajouter une balise à toutes celles pour lesquelles EntityFieldQueryvous souhaitez imprimer la requête, puis l'implémenter hook_query_alter()pour l'intercepter quand c'est une norme SelectQuery, puis la convertir en chaîne pour le débogage:
function MYMODULE_query_alter($query){if($query->hasTag('efq_debug')){
dpm((string)$query);}}
$q =newEntityFieldQuery;
$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 lorsque vous utiliserez MySQL comme système de stockage sur le terrain.
Sonne bien en théorie, mais qu'en est-il des commentaires sur la question? EFQ n'implémente pas __toString ()?
Letharion
4
Au moment où il arrive à hook_query_alter()la requête n'est EntityFieldQueryplus, il a été converti en un standard db_select(), donc ça __tostring()marche très bien :) Depuis que ça marche, je l'ai beaucoup utilisé et ça marche plutôt bien
Clive
Confirmé que la conversion en chaîne fonctionne une fois la requête terminée hook_query_alter().
jhedstrom
Pour voir les arguments de la requête (": type_entité" dans l'exemple ci-dessus), vous pouvez utiliser dpm ($ query-> arguments ());
sanzante
13
Plutôt que de rouler votre propre hook_query_alter (), vous pouvez laisser le module Devel faire le gros du travail pour vous en ajoutant la debugbalise:
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.
belle solution alternative à développer. Impossible de trouver ce module directement sur DO car ils ont supprimé le bloc de module connexe qui était là auparavant.
kiranking
1
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, 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.
Notez que ce dtrussn'est qu'un script qui utilise DTrace, vous pouvez donc envisager une implémentation directe des sondes statiques PHP DTrace ou DTracing MySQL en écrivant votre propre script.
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);}}
Réponses:
C'est un peu un hack, mais vous pouvez ajouter une balise à toutes celles pour lesquelles
EntityFieldQuery
vous souhaitez imprimer la requête, puis l'implémenterhook_query_alter()
pour l'intercepter quand c'est une normeSelectQuery
, puis la convertir en chaîne pour le débogage:C'est un peu un hack mais ça fait l'affaire. La sortie de ce qui précède est:
Vraisemblablement, cela ne fonctionnera que lorsque vous utiliserez MySQL comme système de stockage sur le terrain.
la source
hook_query_alter()
la requête n'estEntityFieldQuery
plus, il a été converti en un standarddb_select()
, donc ça__tostring()
marche très bien :) Depuis que ça marche, je l'ai beaucoup utilisé et ça marche plutôt bienhook_query_alter()
.Plutôt que de rouler votre propre hook_query_alter (), vous pouvez laisser le module Devel faire le gros du travail pour vous en ajoutant la
debug
balise:Cela imprimera la requête à l'écran, comme vous le
dpq()
feriez.la source
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.
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.
la source
Si vous téléchargez la version dev de Nice DPQ (ou n'importe quoi => 1.1), vous pouvez simplement faire:
et vous obtiendrez bien la requête dpm'ed :). La partie importante dans le code ci-dessus est addTag ('nicedpq') - qui déclenche le
dpm()
.la source
Vous pouvez essayer de le déboguer via XDebug . Une fois installé, faites
xdebug_start_trace()
avant le code, etxdebug_stop_trace()
après cela, 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
requêtes spécifiques
Notez que ce
dtruss
n'est qu'un script qui utilise DTrace, vous pouvez donc envisager une implémentation directe des sondes statiques PHP DTrace ou DTracing MySQL en écrivant votre propre script.En savoir plus: Débogage avancé du noyau Drupal à l'aide de la ligne de commande (strace & tcpdump)
la source
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.la source