EntityFieldQueryをデバッグしますか?


27

誤動作しているモジュールがあります。EFQは予期しない結果を再試行していますが、コードを見ただけではその理由がわかりません。EFQに相当するdpq()はありますか?それらをデバッグする他の方法は?


同様の質問:drupal.stackexchange.com/questions/33473/...。クエリオブジェクトを文字列にキャストして検査し、SQLが何か手掛かりを与えているかどうかを確認できますか?
クライブ

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()を実装していませんか?
レサリオン

4
それが取得時点でhook_query_alter()のクエリではないEntityFieldQuery、それ以上、標準にダウン変換されていますdb_select()ので、__tostring()素晴らしい作品:)から、この作業以来、私はそれを非常に多く使用されてきたし、それはかなりうまく機能
クライヴ

クエリがに到達すると、文字列へのキャストが機能することを確認しましたhook_query_alter()
jhedstrom

クエリ引数(上記の例では ":entity_type")を表示するには、dpm($ query-> arguments());を使用できます。
サンザンテ14年

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されます:)。上記のコードの重要な部分はaddTag( 'nicedpq')です -これはをトリガーしdpm()ます。


開発するための素敵な代替回避策。DOを介して直接そのモジュールを見つけることができませんでした。関連するモジュールブロックを削除していたためです。
15年

1

XDebugを介してデバッグを試みることができます。インストールしたらxdebug_start_trace()、コードの前に実行xdebug_stop_trace()し、その後実行すると、実行された内容と場所が明確なトレースログになります。

また、MySQL構成でクエリロガーを有効にできます。

もう1つの方法は、デバッガーのようなstrace / truss / dtrussを使用することです。

dtrussを使用した例:

  • すべてのクエリ

    sudo dtruss -t read -n mysqld
  • 特定のクエリ

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

dtrussばかりのDTraceを使用するスクリプトでは、あなたが直接実装検討することができるPHP DTraceの静的プローブまたはDTracing MySQLを独自のスクリプトを書くことで。

詳細:コマンドラインを使用したDrupalコアの高度なデバッグ(straceおよびtcpdump)


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.