$GLOBALS['wp_the_query'] vs global $wp_query in WordPress
Qual è la differenza tra $GLOBALS['wp_the_query']
e global $wp_query
?
Perché preferire uno rispetto all'altro?

Ti sei dimenticato uno, $GLOBALS['wp_query']
. Per tutti gli scopi, $GLOBALS['wp_query'] === $wp_query
. Tuttavia, $GLOBALS['wp_query']
è migliore per la leggibilità e dovrebbe essere utilizzato al posto di $wp_query
, MA rimane una preferenza personale.
Ora, in un mondo perfetto dove gli unicorni governano il mondo, $GLOBALS['wp_the_query'] === $GLOBALS['wp_query'] === $wp_query
. Di default, questo dovrebbe essere vero. Se guardiamo dove questi global sono impostati (wp-settings.php
), vedrai che l'oggetto della query principale è memorizzato in $GLOBALS['wp_the_query']
e $GLOBALS['wp_query']
è solo una copia duplicata di $GLOBALS['wp_the_query']
.
/**
* Oggetto Query di WordPress
* @global WP_Query $wp_the_query
* @since 2.0.0
*/
$GLOBALS['wp_the_query'] = new WP_Query();
/**
* Mantiene il riferimento a @see $wp_the_query
* Usa questo globale per le query di WordPress
* @global WP_Query $wp_query
* @since 1.5.0
*/
$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
Il motivo per fare così, è perché WordPress ha visto l'arrivo di query_posts
nella versione 1.5.
function query_posts($query) {
$GLOBALS['wp_query'] = new WP_Query();
return $GLOBALS['wp_query']->query($query);
}
Come puoi vedere, query_posts
imposta l'oggetto della query principale alla query personalizzata corrente in esecuzione. Questo rompe l'integrità dell'oggetto della query principale, che ti dà dati errati, quindi qualsiasi cosa che si basa sull'oggetto della query principale è rotta a causa di dati sbagliati.
Un modo per contrastare questo era creare un altro globale per memorizzare l'oggetto della query principale, $GLOBALS['wp_the_query']
che è stato introdotto nella versione 2.0.0. Questo nuovo globale contiene l'oggetto della query principale e $GLOBALS['wp_query']
è solo una copia. Attraverso wp_reset_query()
, ora potevamo resettare $GLOBALS['wp_query']
all'oggetto della query principale originale per ripristinarne l'integrità.
Ma questo non è un mondo perfetto, e query_posts
è il diavolo in persona. Nonostante migliaia di avvertimenti, le persone usano ancora query_posts
. Oltre a rompere la query principale, riesegue la query principale, rendendola molto più lenta di una normale query personalizzata con WP_Query
. Molte persone inoltre non resettano la query query_posts
con wp_reset_query()
quando hanno finito, il che rende query_posts
ancora più malvagio.
Poiché non possiamo fare nulla al riguardo, e non possiamo impedire a plugin e temi di usare query_posts
e non possiamo mai sapere se una query query_posts
è stata resettata con wp_reset_query()
, abbiamo bisogno di una copia più affidabile dell'oggetto della query principale che sappiamo ci darà dati corretti al 99,99999% affidabili. È qui che $GLOBALS['wp_the_query']
è utile poiché nessun codice correlato a WordPress può cambiarne il valore (eccetto attraverso i filtri e le azioni all'interno di WP_Query
stesso).
Prova rapida, esegui il seguente
var_dump( $GLOBALS['wp_the_query'] );
var_dump( $GLOBALS['wp_query'] );
query_posts( 's=crap' );
var_dump( $GLOBALS['wp_the_query'] );
var_dump( $GLOBALS['wp_query'] );
e controlla i risultati. $GLOBALS['wp_the_query']
non è cambiato, mentre $GLOBALS['wp_query']
sì. Quindi quale è più affidabile?
Nota finale, $GLOBALS['wp_the_query']
NON è un sostituto per wp_reset_query()
. wp_reset_query()
dovrebbe sempre essere usato con query_posts
, e query_posts
non dovrebbe mai essere usato.
PER CONCLUDERE
Se hai bisogno di codice affidabile che quasi mai fallirà, usa $GLOBALS['wp_the_query']
, se ti fidi e credi nel codice dei plugin e del tema e credi che nessuno usi query_posts
o lo stia usando correttamente, usa $GLOBALS['wp_query']
o $wp_query
.
IMPORTANTE MODIFICA
Rispondendo a domande su questo sito da un paio d'anni, ho visto molti utenti usare $wp_query
come variabile locale, che a sua volta rompe anche l'oggetto della query principale. Questo aumenta ulteriormente la vulnerabilità di $wp_query
.
Ad esempio, alcune persone fanno questo
$wp_query = new WP_Query( $args );
che in sostanza è esattamente la stessa cosa che fa query_posts
.

query_posts() modifica global $wp_query
. global $wp_the_query
mantiene il riferimento alla query principale

Il mio commento non era inteso come una correzione, quindi mi scuso se è sembrato così. Stavo solo riassumendo (TL;DR se vuoi) mentre evidenziavo quello che credo essere uno degli aspetti più significativi di $wp_the_query
in relazione al metodo WP_Query::is_main_query()
, che non era stato menzionato :D

@EvanMattson Scusa, ho frainteso il tuo primo commento ;-). Sì, is_main_query()
, che è un wrapper per WP_Query::is_main_query()
, confronta l'oggetto query corrente con l'oggetto query principale salvato in $GLOBALS['wp_the_query']
. Questo è molto importante quando esegui azioni pre_get_posts
e vuoi indirizzare solo la query principale ;-)

Risposta molto ben fatta! @EvanMattson Avresti dovuto farlo come [modifica].

Potresti includere un riferimento alla funzione is_main_query
nella sezione *IMPORTANT EDIT? Oggi stavo usando pre_get_posts
e ho trovato estremamente utile utilizzare questa funzione mentre esaminavo $wp_query
.

La parola chiave global importa la variabile nell'ambito locale, mentre $GLOBALS ti concede solo l'accesso alla variabile.
Per elaborare, se usi global $wp_the_query;
puoi usare $wp_the_query
nell'ambito locale senza dover usare nuovamente la parola global. Quindi fondamentalmente global $wp_the_query
può essere paragonato a $wp_the_query = $GLOBALS['wp_the_query']
MODIFICA
Ho letto male wp_query come wp_the_query, quindi la mia risposta non è una risposta completa alla domanda ma fornisce comunque informazioni generali sulla differenza tra global $variable
e $GLOBALS['variable']
