EntityFieldQuery를 디버그 하시겠습니까?


27

오작동하는 모듈이 있습니다. EFQ가 예기치 않은 결과를 복원하고 있지만 코드를 살펴보면 이유를 알 수 없습니다 . EFQ에 해당 하는 dpq ()가 있습니까? 그들을 디버깅하는 다른 방법?


비슷한 질문 : drupal.stackexchange.com/questions/33473/… . 쿼리 개체를 문자열로 캐스팅하여 SQL에 힌트가 있는지 검사 할 수 있습니까?
Clive

1
그러나 좋은 제안 : 복구 가능한 치명적 오류 : EntityFieldQuery 클래스의 객체를 문자열로 변환 할 수 없습니다 :(
Letharion

답변:


36

그것은 약간의 해킹이지만 EntityFieldQuery쿼리 인쇄에 관심이 있는 태그를 추가 한 다음 hook_query_alter()표준 SelectQuery인 경우 인터셉트하여 구현 하여 디버깅을 위해 문자열로 캐스트 할 수 있습니다.

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

그것은 약간의 해킹이지만 트릭을 수행합니다. 위의 결과는 다음과 같습니다.

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

아마도 이것은 필드 스토리지 시스템으로 MySQL을 사용할 때만 작동합니다.


이론적으로는 훌륭하지만 질문에 대한 의견은 어떻습니까? EFQ는 __toString ()을 구현하지 않습니까?
Letharion

4
그 때까지는이에 도착 hook_query_alter()쿼리가 아닌 EntityFieldQuery더 이상,이 표준에 아래로 변환 된 것 db_select()때문에, __tostring()그것을 꽤 많이 사용하고 I에서이 작업 때문에 :) 잘 작동하고 꽤 잘 작동
클라 이브

쿼리가 도착하면 문자열로 캐스트가 작동 함을 확인했습니다 hook_query_alter().
jhedstrom

쿼리 인수 (위의 예에서 ": entity_type")를 보려면 dpm ($ query-> arguments ());
sanzante

13

자신의 hook_query_alter ()를 굴리는 대신 태그 를 추가하여 Devel 모듈이 무거운 작업을 수행 하도록 할 수 있습니다 debug.

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

이렇게하면 쿼리가 화면과 같이 화면에 인쇄됩니다 dpq().


4

@Clive 답변에 추가하면 일반적으로 값과 함께 자리 표시 자와 함께 쿼리가 인쇄됩니다. 조회와 함께 값을 인쇄하려면 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();

몇 줄의 코드에 모듈을 설치하는 것은 좋지 않습니다. 그래서 위에서 언급 한 솔루션을 선택했습니다.


2

Nice DPQ 의 개발 버전 (또는 무엇이든 => 1.1) 을 다운로드하면 다음 과 같이 할 수 있습니다.

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

그리고 당신은 dpm'ed 쿼리를 멋지게 얻을 것입니다 :). 코드의 중요한 부분은 위이다 ( 'nicedpq') addTag 트리거하는 그 - dpm().


좋은 대체 해결 방법. 이전에 있던 관련 모듈 블록을 제거했기 때문에 DO 바로 위에 해당 모듈을 찾을 수 없습니다.
kiranking

1

XDebug 를 통해 디버깅을 시도 할 수 있습니다 . 일단 설치되면, xdebug_start_trace()코드 전에, 그리고 그 xdebug_stop_trace()후에, 무엇이 실행되었는지와 어디에서 명확한 추적 로그를 보게 될 것입니다.

또한 MySQL 구성에서 쿼리 로거를 활성화 할 수 있습니다.

다른 방법은 디버거와 같은 strace / truss / dtrus를 사용하는 것입니다.

dtruss를 사용한 예 :

  • 모든 쿼리

    sudo dtruss -t read -n mysqld
  • 특정 검색어

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

참고 dtruss단지의 DTrace를 사용하는 스크립트입니다, 그래서 당신의 직접적인 구현 고려할 수있다 PHP의 DTrace 정적 프로브 또는 DTracing MySQL이 자신의 스크립트를 작성하여.

더 읽어보기 : 커맨드 라인 (strace & tcpdump)을 이용한 Drupal 코어의 고급 디버깅


0

이 기능을 모듈에 추가하십시오. 그런 다음 debugEFQ에 태그 를 추가하십시오 . 조회를 인쇄하려면 Devel 모듈이 사용 가능해야합니다.

/**
 * 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);
  }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.