Tengo un módulo que se está portando mal. Un EFQ está recuperando resultados inesperados, pero no puedo ver por qué solo mirando el código. ¿Hay un equivalente dpq () para EFQ? ¿Otras formas de depurarlos?
Pregunta similar: drupal.stackexchange.com/questions/33473/… . ¿Puedes convertir el objeto de consulta en una cadena para inspeccionarlo y ver si el SQL da alguna pista?
Clive
1
Grandes sugerencias, sin embargo: Error fatal recuperable: el objeto de la clase EntityFieldQuery no se pudo convertir en cadena :(
Letharion
Respuestas:
36
Es un truco, pero puede agregar una etiqueta a cualquiera EntityFieldQueryque le interese imprimir la consulta, luego implementarla hook_query_alter()para interceptarla cuando sea un estándar SelectQueryy luego convertirla en cadena para la depuración:
function MYMODULE_query_alter($query){if($query->hasTag('efq_debug')){
dpm((string)$query);}}
$q =newEntityFieldQuery;
$q->entityCondition('entity_type','node')->addTag('efq_debug')->execute();
Es un poco hack pero funciona. La salida para lo anterior es:
SELECT node.nid AS entity_id, node.vid AS revision_id, node.type AS bundle,:entity_type
AS entity_type
FROM {node} node
Presumiblemente, esto solo funcionará cuando se use MySQL como sistema de almacenamiento de campo.
Suena genial en teoría, pero ¿qué pasa con los comentarios sobre la pregunta? EFQ no implementa __toString ()?
Letharion
44
Para cuando llega hook_query_alter()la consulta ya no EntityFieldQueryexiste, se ha convertido a un estándar db_select(), por lo que __tostring()funciona muy bien :) Desde que lo resolví, lo he estado usando bastante y funciona bastante bien
Clive
Confirmó que la conversión a cadena funciona una vez que llega la consulta hook_query_alter().
jhedstrom
Para ver los argumentos de la consulta (": entity_type" en el ejemplo anterior) puede usar dpm ($ query-> argumentos ());
sanzante
13
En lugar de lanzar su propio hook_query_alter (), puede dejar que el módulo Devel haga el trabajo pesado por usted agregando la debugetiqueta:
Agregando a la respuesta @Clive, que generalmente imprime la consulta con el marcador de posición no junto con el valor. Para imprimir el valor con la consulta, use el siguiente código debajo de hook_query_alter.
buena solución alternativa para desarrollar. No se pudo encontrar ese módulo directamente sobre DO porque eliminaron el bloque de módulo relacionado que estaba allí antes.
kiranking
1
Puede intentar depurarlo a través de XDebug . Una vez instalado, haga xdebug_start_trace()antes del código, y xdebug_stop_trace()después de eso, tendrá un registro de seguimiento claro qué se ejecutó y dónde.
También puede habilitar el registrador de consultas en la configuración de MySQL.
El otro método es usar strace / truss / dtruss como depuradores.
Tenga en cuenta que dtrusses solo un script que utiliza DTrace, por lo que puede considerar una implementación directa de las sondas estáticas PHP DTrace o DTracing MySQL escribiendo su propio script.
Agregue esta función a su módulo. Luego, agregue la etiqueta debuga cualquier EFQ. Requiere que el módulo Devel esté habilitado para imprimir la consulta.
/**
* 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);}}
Respuestas:
Es un truco, pero puede agregar una etiqueta a cualquiera
EntityFieldQuery
que le interese imprimir la consulta, luego implementarlahook_query_alter()
para interceptarla cuando sea un estándarSelectQuery
y luego convertirla en cadena para la depuración:Es un poco hack pero funciona. La salida para lo anterior es:
Presumiblemente, esto solo funcionará cuando se use MySQL como sistema de almacenamiento de campo.
fuente
hook_query_alter()
la consulta ya noEntityFieldQuery
existe, se ha convertido a un estándardb_select()
, por lo que__tostring()
funciona muy bien :) Desde que lo resolví, lo he estado usando bastante y funciona bastante bienhook_query_alter()
.En lugar de lanzar su propio hook_query_alter (), puede dejar que el módulo Devel haga el trabajo pesado por usted agregando la
debug
etiqueta:Esto imprimirá la consulta a la pantalla, tal como lo
dpq()
haría.fuente
Agregando a la respuesta @Clive, que generalmente imprime la consulta con el marcador de posición no junto con el valor. Para imprimir el valor con la consulta, use el siguiente código debajo de hook_query_alter.
No es una buena práctica instalar un módulo para las pocas líneas de código. Es por eso que opté por la solución antes mencionada.
fuente
Si descarga la versión de desarrollo de Nice DPQ (o cualquier cosa => 1.1), simplemente puede hacer:
y obtendrá la consulta dpm'ed muy bien :). La parte importante en el código anterior es addTag ('nicedpq') , que activa el
dpm()
.fuente
Puede intentar depurarlo a través de XDebug . Una vez instalado, haga
xdebug_start_trace()
antes del código, yxdebug_stop_trace()
después de eso, tendrá un registro de seguimiento claro qué se ejecutó y dónde.También puede habilitar el registrador de consultas en la configuración de MySQL.
El otro método es usar strace / truss / dtruss como depuradores.
Ejemplo usando dtruss:
todas las consultas
consultas específicas
Tenga en cuenta que
dtruss
es solo un script que utiliza DTrace, por lo que puede considerar una implementación directa de las sondas estáticas PHP DTrace o DTracing MySQL escribiendo su propio script.Leer más: Depuración avanzada del núcleo de Drupal usando la línea de comando (strace & tcpdump)
fuente
Agregue esta función a su módulo. Luego, agregue la etiqueta
debug
a cualquier EFQ. Requiere que el módulo Devel esté habilitado para imprimir la consulta.fuente