$GLOBALS['wp_the_query'] vs global $wp_query în WordPress
Care este diferența dintre $GLOBALS['wp_the_query']
și global $wp_query
?
De ce am prefera una față de cealaltă?

Ai ratat unul, $GLOBALS['wp_query']
. Pentru toate scopurile, $GLOBALS['wp_query'] === $wp_query
. Totuși, $GLOBALS['wp_query']
este mai bun pentru lizibilitate și ar trebui folosit în loc de $wp_query
, DAR, aceasta rămâne o preferință personală.
Acum, într-o lume perfectă în care unicornii conduc lumea, $GLOBALS['wp_the_query'] === $GLOBALS['wp_query'] === $wp_query
. În mod implicit, acest lucru ar trebui să fie adevărat. Dacă ne uităm unde sunt setate aceste globale (wp-settings.php
), vei vedea că obiectul principal de interogare este stocat în $GLOBALS['wp_the_query']
și $GLOBALS['wp_query']
este doar o copie duplicată a $GLOBALS['wp_the_query']
.
/**
* Obiectul WordPress Query
* @global WP_Query $wp_the_query
* @since 2.0.0
*/
$GLOBALS['wp_the_query'] = new WP_Query();
/**
* Păstrează referința către @see $wp_the_query
* Folosește această globală pentru interogările WordPress
* @global WP_Query $wp_query
* @since 1.5.0
*/
$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
Motivul pentru care s-a făcut astfel este pentru că WordPress a văzut apariția funcției query_posts
în versiunea 1.5.
function query_posts($query) {
$GLOBALS['wp_query'] = new WP_Query();
return $GLOBALS['wp_query']->query($query);
}
După cum poți vedea, query_posts
setează obiectul principal de interogare la interogarea personalizată curentă care rulează. Acest lucru rupe integritatea obiectului principal de interogare, care îți oferă date incorecte, astfel încât orice se bazează pe obiectul principal de interogare este stricat din cauza datelor greșite.
O modalitate de a contracara acest lucru a fost crearea unei alte globale pentru a stoca obiectul principal de interogare, $GLOBALS['wp_the_query']
, care a fost introdusă în versiunea 2.0.0. Această nouă globală păstrează obiectul principal de interogare, iar $GLOBALS['wp_query']
este doar o copie. Prin wp_reset_query()
, putem acum reseta $GLOBALS['wp_query']
înapoi la obiectul principal de interogare original pentru a-i restabili integritatea.
Dar aceasta nu este o lume perfectă, iar query_posts
este diavolul însuși. În ciuda miilor de avertismente, oamenii încă folosesc query_posts
. Pe lângă faptul că strică interogarea principală, aceasta rulează din nou interogarea principală, făcând-o mult mai lentă decât o interogare personalizată normală cu WP_Query
. Mulți oameni nu resetează nici interogarea query_posts
cu wp_reset_query()
când au terminat, ceea ce face query_posts
și mai rău.
Pentru că nu putem face nimic în legătură cu asta și nu putem opri pluginurile și temele să folosească query_posts
și nu putem ști niciodată dacă o interogare query_posts
a fost resetată cu wp_reset_query()
, avem nevoie de o copie mai fiabilă a obiectului principal de interogare despre care știm că ne va oferi date corecte în 99,99999% din cazuri. Aici este util $GLOBALS['wp_the_query']
, deoarece niciun cod WordPress nu poate schimba valoarea acesteia (cu excepția filtrelor și acțiunilor din interiorul WP_Query
însuși).
O dovadă rapidă, rulează următoarele:
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'] );
și verifică rezultatele. $GLOBALS['wp_the_query']
nu s-a schimbat, dar $GLOBALS['wp_query']
s-a schimbat. Deci, care este mai fiabil?
Notă finală, $GLOBALS['wp_the_query']
NU este un înlocuitor pentru wp_reset_query()
. wp_reset_query()
ar trebui întotdeauna folosit cu query_posts
, iar query_posts
nu ar trebui folosit niciodată.
ÎN CONCLUZIE
Dacă ai nevoie de un cod fiabil care aproape niciodată nu va eșua, folosește $GLOBALS['wp_the_query']
. Dacă ai încredere și crezi în codul pluginurilor și temelor și crezi că nimeni nu folosește query_posts
sau o folosește corect, folosește $GLOBALS['wp_query']
sau $wp_query
.
EDITARE IMPORTANTĂ
Răspunzând la întrebări pe acest site de câțiva ani, am văzut mulți utilizatori folosind $wp_query
ca variabilă locală, ceea ce, la rândul său, strică și obiectul principal de interogare. Acest lucru crește și mai mult vulnerabilitatea $wp_query
.
De exemplu, unii oameni fac asta:
$wp_query = new WP_Query( $args );
care, în esență, este exact același lucru pe care îl face query_posts
.

query_posts() modifică global $wp_query
. global $wp_the_query
păstrează referința către interogarea principală

Comentariul meu nu a fost menit drept corectură, așa că îmi cer scuze dacă a dat impresia asta. Doar rezumam (TL;DR, dacă vrei) subliniind ceea ce cred că este unul dintre cele mai importante aspecte ale $wp_the_query
în legătură cu metoda WP_Query::is_main_query()
, care nu a fost menționată :D

@EvanMattson Îmi cer scuze, am înțeles greșit primul tău comentariu ;-). Da, is_main_query()
, care este un wrapper pentru WP_Query::is_main_query()
, verifică obiectul curent de interogare față de obiectul principal de interogare salvat în $GLOBALS['wp_the_query']
. Acest lucru este foarte important când rulezi acțiuni pre_get_posts
și vrei să te adresezi doar interogării principale ;-)

Răspuns foarte bine structurat! @EvanMattson Ar fi trebuit să fie o [editare].

Poți include mențiunea funcției is_main_query
în secțiunea *EDITARE IMPORTANTĂ? Am folosit pre_get_posts
astăzi și am găsit extrem de utilă utilizarea acestei funcții, având în vedere că mă uitam la $wp_query
.

Cuvântul cheie global
importă variabila în scope-ul local, în timp ce $GLOBALS
doar îți oferă acces la variabilă.
Pentru a clarifica, dacă folosești global $wp_the_query;
poți utiliza $wp_the_query
în scope-ul local fără a mai folosi cuvântul cheie global din nou. Deci, practic, global $wp_the_query
poate fi comparat cu $wp_the_query = $GLOBALS['wp_the_query']
EDITARE
Am confundat wp_query
cu wp_the_query
, așa că răspunsul meu nu este complet pentru întrebare, dar totuși oferă informații generale despre diferența dintre global $variable
și $GLOBALS['variable']
.
