$ GLOBALS ['wp_the_query'] vs global $ wp_query

16

¿Cuál es la diferencia entre $GLOBALS['wp_the_query']y global $wp_query?

¿Por qué preferir uno sobre el otro?

Nathan Powell
fuente
2
¡Diría que global $wp_querysolo responda su pregunta en una línea!
Sumit
¿Cuál es la diferencia?
Nathan Powell

Respuestas:

27

Te has perdido uno $GLOBALS['wp_query']. A todos los efectos $GLOBALS['wp_query'] === $wp_query. $GLOBALS['wp_query']Sin embargo, es mejor para la legibilidad y debe usarse en lugar de $wp_query, PERO, que sigue siendo una preferencia personal

Ahora, en un mundo perfecto, donde los unicornios gobiernan el mundo, $GLOBALS['wp_the_query'] === $GLOBALS['wp_query'] === $wp_query. Por defecto, esto debería ser cierto. Si observamos dónde están establecidos estos globales ( wp-settings.php), verá que el objeto de consulta principal está almacenado $GLOBALS['wp_the_query']y $GLOBALS['wp_query']es solo una copia duplicada 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 razón para hacerlo de esta manera es porque WordPress vio la llegada de la query_postsversión 1.5.

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

Como puede ver, query_postsestablece el objeto de consulta principal en la ejecución de consulta personalizada actual. Esto rompe la integridad del objeto de consulta principal, que le da datos incorrectos, por lo que todo lo que se base en el objeto de consulta principal se rompe debido a datos incorrectos.

Una forma de contrarrestar esto fue crear otro global para almacenar el objeto de consulta principal, $GLOBALS['wp_the_query']que se introdujo en la versión 2.0.0. Este nuevo global contiene el objeto de consulta principal y $GLOBALS['wp_query']solo una copia. A través de esto wp_reset_query(), ahora podríamos restablecer $GLOBALS['wp_query']el objeto de consulta principal original para restaurar su integridad.

Pero este no es un mundo perfecto, y query_postsson el mismo diablo. Aunque miles de advertencias, la gente todavía lo usa query_posts. Además de romper la consulta principal, vuelve a ejecutar la consulta principal, haciéndola mucho más lenta como una consulta personalizada normal con WP_Query. Muchas personas tampoco restablecen la query_postsconsulta wp_reset_query()cuando se hace, lo que hace query_postsaún más malvado.

Debido a que no podemos hacer nada al respecto, y no podemos detener el uso de complementos y temas query_postsy nunca podemos saber si query_postsse restableció una consulta wp_reset_query(), necesitamos una copia más confiable del objeto de consulta principal que sabemos nos dará un 99.99999% de confiabilidad, correcta datos. Ahí es donde $GLOBALS['wp_the_query']es útil, ya que ningún código relacionado con WordPress puede cambiar su valor ( excepto a través de los filtros y acciones dentro de WP_Querysí mismo ).

Prueba rápida, ejecute lo siguiente

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

y verifica los resultados. $GLOBALS['wp_the_query']no ha cambiado, y lo $GLOBALS['wp_query']ha hecho. Entonces, ¿cuál es más confiable?

Nota final, NO$GLOBALS['wp_the_query'] es un reemplazo para . debe siempre ser utilizado con , y debe no ser utilizado.wp_reset_query()wp_reset_query()query_postsquery_posts

PARA CONCLUIR

Si necesita un código confiable que casi nunca fallará, use $GLOBALS['wp_the_query'], si confía y cree en los complementos y el código del tema y cree que nadie lo usa query_postso lo está usando correctamente, use $GLOBALS['wp_query']o$wp_query

EDICION IMPORTANTE

Al responder preguntas en este sitio durante un par de años, vi que muchos usuarios lo usaban $wp_querycomo una variable local, lo que a su vez también rompe el objeto de consulta principal. Esto aumenta aún más la vulnerabilidad de la $wp_query.

Como ejemplo, algunas personas a esto

$wp_query = new WP_Query( $args );

que en esencia es exactamente lo mismo que query_postsestamos haciendo

Pieter Goosen
fuente
1
query_posts () cambia global $wp_query. global $wp_the_querycontiene la referencia a la consulta principal
Evan Mattson
Mi comentario no pretendía ser una corrección, por lo que me disculpo si lo hizo. Simplemente estaba resumiendo (TL; DR si lo desea) mientras señalaba lo que creo que es uno de los aspectos más significativos en $wp_the_querylo que respecta al WP_Query::is_main_query()método, que no se mencionó: D
Evan Mattson
@EvanMattson Disculpas, entendí mal tu primer comentario ;-). Sí, is_main_query()que es un contenedor para el WP_Query::is_main_query()que se compara el objeto de consulta actual con el objeto de consulta principal guardado en $GLOBALS['wp_the_query']. Esto es bastante importante cuando ejecuta pre_get_postsacciones y solo desea orientar la consulta principal ;-)
Pieter Goosen
Bastante bien hecho respuesta! @EvanMattson Eso debería haber sido una edición .
Kaiser
¿Puede incluir la mención de la is_main_queryfunción en la sección * EDICIÓN IMPORTANTE? Estaba usando pre_get_postshoy y encontré completamente útil usar esa función desde que estaba mirando $wp_query.
Nathan Powell
2

Básicamente uno es copia del otro. Echa un vistazo wp-settings.php, líneas 292-305:

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

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

La palabra clave global importa la variable en el ámbito local, mientras que $ GLOBALS solo le otorga acceso a la variable.

Para elaborar, si lo usa global $wp_the_query; , puede usarlo $wp_the_querydentro del ámbito local sin usar la palabra global nuevamente. Así que básicamente global $wp_the_queryse puede comparar con$wp_the_query = $GLOBALS['wp_the_query']

EDITAR

Leí mal wp_query para wp_the_query, por lo que mi respuesta no es una respuesta completa a la pregunta, pero aún proporciona información general sobre la diferencia entre global $variabley$GLOBALS['variable']

Jeffrey von Grumbkow
fuente
Por favor, presente una edición ya que esto realmente no es una respuesta a la pregunta original. Solo FYI $GLOBALS['foo']permite anular o desarmar la variable también. Entonces es un poco más de lo que describe aquí.
kaiser