Роздрукувати запит, побудований за допомогою db_select ()


61

Я хочу надрукувати запит, побудований за допомогою db_select (), програмно. Чи є якась функція API, що надається Drupal Abstraction Layer?
Це схоже на вихід запитів у Views, але я хочу надрукувати його зі свого спеціального модуля для налагодження.

Відповіді:


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схоже , це не дозволяє навіть у спробі / уловленні.
Кії

1
Це має бути правильна відповідь.
альберцький

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

У мене є гарне рішення, що ви можете скопіювати / вставити рядок запиту безпосередньо в розділ "SQL" на Phpmyadmin і налагодити ваш запит (я часто використовую цей метод, коли борюся з запитом)

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

Я сподіваюся, що це буде корисним для інших хлопців.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.