打印使用db_select()构建的查询


61

我想以编程方式打印使用db_select()构建的查询。Drupal抽象层提供任何API函数吗?
它类似于Views中的查询输出,但是我想从我的自定义模块中打印它以进行调试。

Answers:


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 2015年

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 2014年

2
dpq()我一生都在哪里!
Lomax

try catch查询失败时,似乎无法在块中工作。因此,如果我无法调试损坏的查询,则对我的情况没有帮助。
Kiee

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 2015年

2
无需膨胀/第3方模块。另外,这适用于尚未执行的查询,因此您可以打印失败并给出错误的查询,dpq即使在try / catch中也不允许这样做。
Kiee

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

我希望这对其他人有用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.