web-dev-qa-db-fra.com

Affiche la requête qui est construite en utilisant db_select ()

Je veux imprimer la requête qui est construite en utilisant db_select () de manière programmatique. Y a-t-il une fonction API fournie par Drupal Abstraction Layer?
C'est similaire à la sortie de requête dans les vues, mais je veux l'imprimer à partir de mon module personnalisé à des fins de débogage.

62
Sithu

SelectQuery implémente SelectQuery::__toString() , qui est appelée dans les contextes où une chaîne est requise.

Considérez le code suivant.

global $theme_key;

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

print $query;

Sa sortie est la suivante.

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

Pour obtenir le tableau d'arguments utilisé pour la requête, vous pouvez appeler SelectQuery::arguments() .

Le code suivant imprime la requête et ses arguments à l'aide des fonctions mises à disposition à partir du module Devel.

global $theme_key;

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

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

screenshot

Le module Devel n'est pas nécessaire, cependant, et vous pouvez drupal_set_message() pour afficher la sortie. Par exemple, vous pouvez utiliser la fonction suivante pour obtenir une chaîne avec les espaces réservés remplacés par leurs valeurs réelles.

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

L'exemple de code précédent que j'ai montré deviendrait le suivant.

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

Notez que SelectQuery::arguments() renvoie le tableau d'arguments de requête uniquement lorsqu'il est appelé après SelectQuery::__toString(), SelectQuery::compile() ou SelectQuery::execute() ; sinon, SelectQuery::arguments() renvoie NULL.

Vous pouvez utiliser une fonction similaire à la suivante pour obtenir la requête de chaîne, avec les espaces réservés remplacés par les arguments.

68
kiamlaluno

Vous pouvez utiliser dpq () pour afficher la requête et dpr () pour afficher le résultat.

  $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.
47
umesh

Une autre option est:

global $theme_key;

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

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

Les réponses ci-dessus sont bonnes lorsque Devel est installé et configuré.

La meilleure façon d'imprimer la requête sans Devel est la suivante.

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

Nous pouvons utiliser l'une des méthodes ci-dessus pour imprimer la requête.

8
KiranD

J'ai une bonne solution que vous pouvez copier/coller votre chaîne de requête directement dans la section "SQL" de Phpmyadmin et déboguer votre requête (j'utilise souvent cette méthode lorsque je lutte avec la requête)

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

J'espère que cela sera utile pour les autres gars.

4
Yusef

Version Drupal 8:

$query = \Drupal::entityQuery('node')
    ->addTag('debug')
    ->execute();
0
Tien Wang