$GLOBALS['wp_the_query'] vs global $wp_query în WordPress

14 mar. 2016, 10:12:16
Vizualizări: 30.4K
Voturi: 23

Care este diferența dintre $GLOBALS['wp_the_query'] și global $wp_query?

De ce am prefera una față de cealaltă?

2
Comentarii

Aș spune global $wp_query doar ca să răspund la întrebarea ta într-un singur rând!

Sumit Sumit
14 mar. 2016 10:17:40

Care este diferența?

Nathan Powell Nathan Powell
14 mar. 2016 10:23:59
Toate răspunsurile la întrebare 3
6
34

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.

14 mar. 2016 11:31:15
Comentarii

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

Evan Mattson Evan Mattson
15 mar. 2016 21:06:01

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

Evan Mattson Evan Mattson
16 mar. 2016 02:37:20

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

Pieter Goosen Pieter Goosen
16 mar. 2016 06:18:22

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

kaiser kaiser
7 apr. 2016 00:49:58

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.

Nathan Powell Nathan Powell
18 mar. 2017 02:50:17

Doar subliniez faptul că global $name și $GLOBALS['name'] sunt sinonime. Ele se referă întotdeauna la același obiect. Deci, există doar două obiecte: global $wp_query și global $wp_the_query

Philipp Philipp
3 sept. 2021 21:58:34
Arată celelalte 1 comentarii
1

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'].

14 mar. 2016 10:27:55
Comentarii

Te rog, trimite o [editare], deoarece aceasta nu este cu adevărat un răspuns la întrebarea inițială. Doar pentru informare, $GLOBALS['foo'] permite și suprascrierea sau eliminarea variabilei. Deci este puțin mai mult decât descrii aici.

kaiser kaiser
7 apr. 2016 00:52:37
0

Practic, unul este o copie a celuilalt.

14 mar. 2016 10:29:21