db_select()を使用して構築されたクエリを出力します


61

プログラムでdb_select()を使用して構築されたクエリを印刷したい。Drupal Abstraction Layerによって提供されるAPI関数はありますか?
これはビューのクエリ出力に似ていますが、デバッグ用にカスタムモジュールから出力したいです。

回答:


67

SelectQueryimplements SelectQuery::__toString()は、文字列が必要なコンテキストで呼び出されます。

次のコードを検討してください。

global $theme_key;

$query = db_select('block')
  ->condition('theme', $theme_key)
  ->condition('status', 1)
  ->fields('block');

print $query;

出力は次のとおりです。

SELECT block.*
FROM 
{block} block
WHERE  (theme = :db_condition_placeholder_0) AND (status = :db_condition_placeholder_1)

クエリに使用される引数の配列を取得するには、を呼び出すことができますSelectQuery::arguments()

次のコードは、Develモジュールから使用可能な関数を使用して、クエリとその引数を出力します。

global $theme_key;

$query = db_select('block')
  ->condition('theme', $theme_key)
  ->condition('status', 1)
  ->fields('block');

dpm((string) $query);
dpm($query->arguments());

スクリーンショット

ただし、Develモジュールは必要ありませんdrupal_set_message()。出力を表示できます。たとえば、次の関数を使用して、プレースホルダーを実際の値に置き換えた文字列を取得できます。

function _get_query_string(SelectQueryInterface $query) {
  $string = (string) $query;
  $arguments = $query->arguments();

  if (!empty($arguments) && is_array($arguments)) {
    foreach ($arguments as $placeholder => &$value) {
      if (is_string($value)) {
        $value = "'$value'";
      }
    }

    $string = strtr($string, $arguments);
  }

  return $string;
}

前に示したコード例は次のようになります。

global $theme_key;

$query = db_select('block')
  ->condition('theme', $theme_key)
  ->condition('status', 1)
  ->fields('block');

drupal_set_message(format_string('Query: %query', array('%query' => _get_query_string($query))));

function _get_query_string(SelectQueryInterface $query) {
  $string = (string) $query;
  $arguments = $query->arguments();

  if (!empty($arguments) && is_array($arguments)) {
    foreach ($arguments as $placeholder => &$value) {
      if (is_string($value)) {
        $value = "'$value'";
      }
    }

    $string = strtr($string, $arguments);
  }

  return $string;
}

SelectQuery::arguments()クエリ引数の配列は、、、またはの後SelectQuery::__toString()に呼び出されたときにのみ返されることに注意してください。そうでなければ、を返します。SelectQuery::compile()SelectQuery::execute()SelectQuery::arguments()NULL

次のような関数を使用して、プレースホルダーを引数に置き換えて文字列クエリを取得できます。


1
のような機能_get_query_string()SelectQueryインターフェースの一部であるはずだったと思います。
-dashohoxha

46

あなたは使用することができます)(DPQ *クエリ、および表示する)DPRを(結果を表示します。

  $query = db_select('users','u');
  $query->fields('u');
  $query->condition('u.uid', 1042);
  $result = $query->execute()->fetchAll();

  dpq($query); // Display the query. 
  dpr($result); // Display the query result.

1
これには、Develモジュールをインストールする必要があることに注意してください。Develを使用する場合(大好き)、これが最も簡単な方法です。
joe_flash

2
dpq()あなたは私の人生のどこにいましたか!
ロマックス

try catchクエリが失敗した場合、ブロックで機能するようには見えません。壊れたクエリをデバッグできない場合、私の場合は役に立ちません。
キエ

19

別のオプションは次のとおりです。

global $theme_key;

$query = db_select('block')
  ->condition('theme', $theme_key)
  ->condition('status', 1)
  ->fields('block');

print strtr((string) $query, $query->arguments());

2
短く簡潔です。
-dashohoxha

2
膨張/サードパーティのモジュールは必要ありません。さらに、これは実行されていないクエリでも機能するため、失敗してエラーが発生したクエリを出力できますがdpq、try / catchでも許可されていないようです。
キエ

1
これが正解です。
albertski

8

上記の回答は、Develをインストールして構成した場合に役立ちます。

Develなしでクエリを印刷する最良の方法は次のとおりです。

$query = db_select('block')
->condition('theme', $theme_key)
->condition('status', 1)
->fields('block');
//One way
echo $query->__toString();
// Second way
echo (string)$query;

上記のいずれかの方法を使用して、クエリを印刷できます。


4

私はあなたがPhpmyadminの「SQL」セクションに直接クエリ文字列をコピー/貼り付けてクエリをデバッグできる良い解決策を持っています(クエリに苦労するとき、私はしばしばこの方法を使用します)

$querystring=$query->__toString();
$querystring=str_replace("{",'',$querystring);
$querystring=str_replace("}",'',$querystring);
foreach($query->getArguments() as $key=> $item){

    if(!$item) {
        $item = 'NULL';
    }
    $querystring=str_replace($key.')',$item.')',$querystring);
}
dpm($querystring);

これが他の人たちにとって役に立つことを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.