Stampa la query che viene creata utilizzando db_select ()


61

Voglio stampare la query che viene creata usando db_select () in modo programmatico. Esiste una funzione API fornita da Drupal Abstraction Layer?
È simile all'output della query in Views, ma voglio stamparlo dal mio modulo personalizzato a scopo di debug.

Risposte:


67

SelectQueryimplementa SelectQuery::__toString(), che viene chiamato nei contesti in cui è richiesta una stringa.

Considera il seguente codice.

global $theme_key;

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

print $query;

Il suo output è il seguente.

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

Per ottenere l'array di argomenti utilizzati per la query, è possibile chiamare SelectQuery::arguments().

Il codice seguente stampa la query e i suoi argomenti usando le funzioni rese disponibili dal modulo Devel.

global $theme_key;

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

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

immagine dello schermo

Il modulo Devel non è necessario, tuttavia, e potresti drupal_set_message()mostrare l'output. Ad esempio, è possibile utilizzare la seguente funzione per ottenere una stringa con i segnaposto sostituiti dai loro valori effettivi.

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

Il precedente codice di esempio che ho mostrato sarebbe diventato il seguente.

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

Si noti che SelectQuery::arguments()restituisce l'array di argomenti di query solo quando viene chiamato dopo SelectQuery::__toString(), SelectQuery::compile()oppure SelectQuery::execute(); altrimenti, SelectQuery::arguments()ritorna NULL.

È possibile utilizzare una funzione simile alla seguente per ottenere la query stringa, con i segnaposto sostituiti con gli argomenti.


1
Penso che una funzione come _get_query_string()avrebbe dovuto far parte SelectQuerydell'interfaccia.
dashohoxha,

46

È possibile utilizzare dpq () per visualizzare la query e dpr () per visualizzare il risultato.

  $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
Si noti che ciò richiede l'installazione del modulo Devel. Se usi Develop (lo adoro), questo è il modo più semplice di procedere.
joe_flash,

2
dpq () dove sei stato tutta la mia vita!
Lomax,

Non sembra funzionare in un try catchblocco quando la query non riesce. Quindi non è utile nel mio caso se non riesco a eseguire il debug della query interrotta.
Kiee,

19

Un'altra opzione è:

global $theme_key;

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

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

2
Breve e conciso davvero.
dashohoxha,

2
Nessun modulo gonfio / di terze parti richiesto. Inoltre, questo funziona su query che non sono state eseguite, quindi puoi stampare una query che fallisce e dà un errore, dpqnon sembra permetterlo nemmeno in un tentativo / cattura.
Kiee,

1
Questa dovrebbe essere la risposta corretta.
albertski,

8

Le risposte sopra sono buone quando hai sviluppato e configurato Develop.

Il modo migliore per stampare la query senza Devel è il seguente.

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

È possibile utilizzare uno dei metodi sopra indicati per stampare la query.


4

Ho una buona soluzione che puoi copiare / incollare la tua stringa di query direttamente nella sezione "SQL" in Phpmyadmin ed eseguire il debug della tua query (uso spesso questo metodo quando faccio fatica con la query)

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

Spero che questo sia utile per gli altri ragazzi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.