$ GLOBALS ['wp_the_query'] vs global $ wp_query

16

Quelle est la difference entre $GLOBALS['wp_the_query']et global $wp_query?

Pourquoi préférer l'un à l'autre?

Nathan Powell
la source
2
Je dirais global $wp_queryjuste pour répondre à votre question en une seule ligne!
Sumit
Quelle est la différence?
Nathan Powell

Réponses:

27

Vous en avez manqué un $GLOBALS['wp_query']. Pour toutes fins utiles, $GLOBALS['wp_query'] === $wp_query. $GLOBALS['wp_query']est cependant meilleur pour la lisibilité et devrait être utilisé à la place de $wp_query, MAIS, cela reste une préférence personnelle

Maintenant, dans un monde parfait où les licornes gouvernent le monde, $GLOBALS['wp_the_query'] === $GLOBALS['wp_query'] === $wp_query. Par défaut, cela devrait être vrai. Si nous regardons où ces globaux sont définis ( wp-settings.php), vous verrez que l'objet de requête principal est stocké $GLOBALS['wp_the_query']et $GLOBALS['wp_query']n'est qu'une copie en double de$GLOBALS['wp_the_query']

/**
 * WordPress Query object
 * @global WP_Query $wp_the_query
 * @since 2.0.0
 */
$GLOBALS['wp_the_query'] = new WP_Query();
/**
 * Holds the reference to @see $wp_the_query
 * Use this global for WordPress queries
 * @global WP_Query $wp_query
 * @since 1.5.0
 */
$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];

La raison de le faire de cette façon est que WordPress a vu l'arrivée de la query_postsversion 1.5.

function query_posts($query) {
    $GLOBALS['wp_query'] = new WP_Query();
    return $GLOBALS['wp_query']->query($query);
}

Comme vous pouvez le voir, query_postsdéfinit l'objet de requête principal sur l'exécution en cours de la requête personnalisée en cours. Cela rompt l'intégrité de l'objet de requête principal, ce qui vous donne des données incorrectes, de sorte que tout ce qui repose sur l'objet de requête principal est rompu en raison de données incorrectes.

Un moyen de contrer cela était de créer un autre global pour stocker l'objet de requête principal, $GLOBALS['wp_the_query']qui a été introduit dans la version 2.0.0. Ce nouveau global contient l'objet de requête principal et $GLOBALS['wp_query']juste une copie. Grâce à wp_reset_query(), nous pouvions maintenant réinitialiser $GLOBALS['wp_query']l'objet de requête principal d'origine pour restaurer son intégrité.

Mais ce n'est pas un monde parfait, et ce query_postssont le diable lui-même. Bien que des milliers d'avertissements, les gens utilisent toujours query_posts. En plus de casser la requête principale, il réexécute la requête principale, ce qui la rend beaucoup plus lente qu'une requête personnalisée normale avec WP_Query. De nombreuses personnes ne réinitialisent pas non plus la query_postsrequête une wp_reset_query()fois terminé, ce qui rend query_postsencore plus le mal.

Parce que nous ne pouvons rien faire à ce sujet, et ne pouvons pas empêcher les plugins et les thèmes d'utiliser query_postset nous ne pouvons jamais savoir si une query_postsrequête a été réinitialisée avec wp_reset_query(), nous avons besoin d'une copie plus fiable de l'objet de requête principal qui, nous le savons, nous donnera 99,99999% fiable, correct Les données. C'est là où $GLOBALS['wp_the_query']est utile car aucun code lié à WordPress ne peut changer sa valeur ( sauf à travers les filtres et les actions à l'intérieur de WP_Querylui-même ).

Épreuve rapide, exécutez ce qui suit

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'] );

et vérifiez les résultats. $GLOBALS['wp_the_query']n'a pas changé, et $GLOBALS['wp_query']a. Alors, quel est le plus fiable?

Note finale, $GLOBALS['wp_the_query']est pas un remplacement pour wp_reset_query(). wp_reset_query()doit toujours être utilisé avec query_postset nequery_posts doit jamais être utilisé.

DE CONCLURE

Si vous avez besoin d'un code fiable qui échouera presque toujours, utilisez $GLOBALS['wp_the_query'], si vous faites confiance et croyez aux plugins et au code de thème et que personne ne l'utilise query_postsou ne l'utilise correctement, utilisez $GLOBALS['wp_query']ou$wp_query

MODIFICATION IMPORTANTE

Être répondre à des questions sur ce site dès maintenant pour quelques années, j'ai vu de nombreux utilisateurs en utilisant $wp_querycomme variable locale, ce qui brise aussi le principal objet de la requête. Cela augmente encore la vulnérabilité du $wp_query.

Par exemple, certaines personnes à ce

$wp_query = new WP_Query( $args );

qui est en substance exactement la même chose que ce que vous query_postsfaites

Pieter Goosen
la source
1
les changements de query_posts ()global $wp_query . global $wp_the_querydétient la référence à la requête principale
Evan Mattson
Mon commentaire n'était pas destiné à être une correction, donc je m'en excuse. Je résumais simplement (TL; DR si vous voulez) tout en soulignant ce que je crois être l'un des aspects les plus importants de $wp_the_queryla WP_Query::is_main_query()méthode, qui n'a pas été mentionné: D
Evan Mattson
@EvanMattson Excuses, j'ai mal compris votre premier commentaire ;-). Oui, is_main_query()qui est un wrapper pour WP_Query::is_main_query()lequel l'objet de requête actuel est comparé à l'objet de requête principal enregistré dans $GLOBALS['wp_the_query']. Ceci est très important lorsque vous exécutez des pre_get_postsactions et que vous souhaitez simplement cibler la requête principale ;-)
Pieter Goosen
Réponse assez bien faite! @EvanMattson Cela aurait dû être une modification .
kaiser
Pouvez-vous inclure la mention de la is_main_queryfonction dans la section * IMPORTANT EDIT? J'utilisais pre_get_postsaujourd'hui et j'ai trouvé très utile d'utiliser cette fonction depuis que je regardais $wp_query.
Nathan Powell
2

Fondamentalement, l'un est une copie de l'autre. Départ wp-settings.php, lignes 292-305:

$GLOBALS['wp_the_query'] = new WP_Query();

$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
denis.stoyanov
la source
2

Le mot-clé global importe la variable dans la portée locale, tandis que $ GLOBALS vous accorde simplement l'accès à la variable.

Pour élaborer, si vous utilisez, global $wp_the_query; vous pouvez utiliser $wp_the_queryà l'intérieur de la portée locale sans utiliser à nouveau le mot global. Donc, fondamentalement, global $wp_the_querypeut être comparé à$wp_the_query = $GLOBALS['wp_the_query']

ÉDITER

J'ai mal lu wp_query pour wp_the_query donc ma réponse n'est pas une réponse complète à la question mais fournit toujours des informations générales sur la différence entre global $variableet$GLOBALS['variable']

Jeffrey von Grumbkow
la source
Veuillez déposer une modification car ce n'est vraiment pas une réponse à la question d'origine. Juste FYI $GLOBALS['foo']permet également de remplacer ou de désactiver la variable. C'est donc un peu plus que ce que vous décrivez ici.
kaiser