¿Cuándo debería usar WP_Query vs query_posts () vs get_posts ()?

Respuestas:

667
  • query_posts()es demasiado simplista y una forma problemática de modificar la consulta principal de una página al reemplazarla con una nueva instancia de la consulta. Es ineficiente (vuelve a ejecutar consultas SQL) y fallará directamente en algunas circunstancias (especialmente a menudo cuando se trata de paginación de publicaciones). Cualquier código WP moderno debería usar métodos más confiables, como hacer uso del pre_get_postsgancho, para este propósito. TL; DR no utiliza query_posts () nunca .

  • get_posts() es muy similar en uso y acepta los mismos argumentos (con algunos matices, como diferentes valores predeterminados), pero devuelve una serie de publicaciones, no modifica las variables globales y es seguro de usar en cualquier lugar.

  • WP_Queryes la clase que potencia tanto detrás de escena, pero también puedes crear y trabajar con tu propia instancia. Un poco más complejo, menos restricciones, también seguro de usar en cualquier lugar.

Rarst
fuente
8
@jjeaton query_posts()es una función de envoltura pequeña WP_Query, lo único que hace (según el diagrama de flujo) es sobrescribir global$wp_query
Rarst
77
@jjeaton Reemplazar query_posts()con WP_Queryno hará ninguna diferencia en el rendimiento, la consulta de la página original todavía se ejecutará porque eso es parte de la carga principal. Esas consultas se ejecutarán incluso si su archivo de plantilla no tiene ningún bucle.
Rarst
116
No puedo librarme de la sensación de que esta es la publicación más genial y votada en WPSE. Debería estar en el Codex también.
kaiser
8
Solo agregaré mi descripción más clara del problema "rendimiento de query_posts ()": el uso de query_posts () o WP_Query dentro de un archivo de plantilla tendrá el mismo costo de ejecución: la consulta que acaba de realizar. El problema discutido en el artículo del códice es que si realmente desea reemplazar la consulta, debe hacerlo filtrando el query_posts original () con el filtro 'parse_query'. De esa manera, solo tiene la consulta original, deseable, en lugar de hacer una segunda consulta para reemplazarla de manera incómoda. query_posts () NUNCA ES EL CAMINO !! ¡NUNCA!
jerclarke
22
Hay una asombrosa explicación increíble de query_posts escrita por John James Jacoby en el blog developer.wordpress.com que elimina todas estas respuestas del agua. El punto principal: query_postsno modificar el bucle principal en absoluto, que sustituye a que después de que ya se ha ejecutado. La mejor manera de modificar el bucle principal es a través de un pre_get_postsfiltro. developer.wordpress.com/2012/05/14/…
Dan Gayle
65

query_posts- Nunca deberías usarlo query_posts. Además de lo que ha dicho @Rarst, el problema realmente grande query_postses que rompe el objeto de consulta principal (almacenado en $wp_query). Muchos complementos y código personalizado se basan en el objeto de consulta principal, por lo que romper el objeto de consulta principal significa que está rompiendo las funcionalidades de los complementos y el código personalizado. Una de esas funciones es la función de paginación más importante, por lo que si interrumpe la consulta principal, interrumpe la paginación.

Para probar qué tan malo query_postses, en cualquier plantilla, haga lo siguiente y compare los resultados

var_dump( $wp_query );
query_posts( '&posts_per_page=-1' );
var_dump( $wp_query );

get_postsy WP_Queryson la forma correcta de construir consultas secundarias ( como publicaciones relacionadas, controles deslizantes, contenido destacado y contenido en portadas estáticas ) con. Cabe señalar, no debe utilizar ninguno de los dos a favor de la consulta principal en la página de inicio, página única o cualquier tipo de página de archivo, ya que romperá la funcionalidad de la página. Si necesita modificar la consulta principal, use pre_get_postspara hacerlo, y no una consulta personalizada. ( ACTUALIZACIÓN: para páginas frontales estáticas y páginas verdaderas, consulte Uso de pre_get_posts en páginas verdaderas y páginas frontales estáticas *)

En esencia, WP_Queryes usado por la consulta principal y también es usado por get_posts, pero aunque los get_posts()usos WP_Query, existen algunas diferencias

  • get_postsson más rápidos que WP_Query. El margen depende de la cantidad de publicaciones totales del sitio. La razón de esto es que get_postspasa 'no_found_rows' => truepor defecto a lo WP_Queryque omite / rompe legalmente la paginación. Con 'no_found_rows' => true, WP_Queryobtiene la cantidad de publicaciones consultadas, luego rescata, donde, de forma predeterminada, busca aún más todas las publicaciones que coinciden con la consulta para calcular la paginación.

    Por esta razón, get_posts()debe usarse solo para consultas no paginadas. Paginar get_postses realmente un gran desastre. WP_Querydebe usarse para todas las consultas paginadas

  • get_posts()no están influenciados por los posts_*filtros donde se WP_Queryve influenciado por estos filtros. La razón es que get_posts, por defecto, pasa 'suppress_filters' => trueaWP_Query

  • get_poststiene un par de parámetros adicionales como include, exclude, numberpostsy category. Estos parámetros se cambian a parámetros válidos WP_Queryantes de pasarlos a WP_Query. includese transforma en post__in, excludedentro post__not_in, categorydentro caty numberpostsdentro posts_per_page. Solo una nota, todos los parámetros que se pueden pasar a WP_Querytrabajar con get_posts, puede ignorar y no utilizar los parámetros predeterminados deget_posts

  • get_postsdevuelve solo la $postspropiedad de WP_Querywhile WP_Querydevuelve el objeto completo. Este objeto es bastante útil cuando se trata de condicionales, paginación y otra información útil que se puede usar dentro del bucle.

  • get_postsno usa el bucle, sino un foreachbucle para mostrar publicaciones. Además, no hay etiquetas de plantilla disponibles de forma predeterminada. setup_postdata( $post )tiene que usarse para hacer que las etiquetas de plantilla estén disponibles. WP_Queryutiliza el bucle y las etiquetas de plantilla están disponibles de forma predeterminada

  • get_postspasa 'ignore_sticky_posts' => 1a WP_Query, get_postspor lo que por defecto ignora las publicaciones adhesivas

De acuerdo con lo anterior, si usar get_postso WP_Querydepende de usted y qué necesita realmente de la consulta. Lo anterior debe guiarlo en su elección

Pieter Goosen
fuente
1
Ojalá pudiera respuestas favoritas. Esto explica mucho.
Patrik Alienus
1
¡Gran explicación! "get_posts () debería usarse solo para consultas no paginadas. Paginar get_posts es realmente un gran desastre. WP_Query debería usarse para todas las consultas paginadas" Es básicamente todo lo que alguien necesita saber.
Bullyen
32

La diferencia básica es que query_posts()es realmente solo para modificar el Loop actual. Una vez que hayas terminado, es necesario restablecer el bucle y enviarlo de manera alegre. Este método también es un poco más fácil de entender, simplemente porque su "consulta" es básicamente una cadena de URL que pasa a la función, así:

query_posts('meta_key=color&meta_value=blue'); 

Por otro lado, WP_Queryes más una herramienta de propósito general, y es más como escribir consultas MySQL directamente que query_posts()lo que es. También puede usarlo en cualquier lugar (no solo en el bucle) y no interfiere con las consultas de publicaciones que se ejecutan actualmente.

Tiendo a usar WP_Querymás a menudo, como sucede. Realmente, todo se reducirá a su caso específico.

nickmjones
fuente
15

Simplemente no hay necesidad de usar query_posts(). Todo lo que hace es crear una instancia de un nuevo objeto WP_Query y reasignar ese nuevo objeto global wp_query.

Como referencia, la siguiente es esa query_posts()función real .

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

Cree una instancia de su propio objeto WP_Query si desea crear un script de consulta personalizado en profundidad. O úselo get_posts()si todo lo que necesita hacer es alguna manipulación ligera aquí y allá.

En cualquier caso, recomiendo hacerte un favor e ir wp_includes/query.phpy examinar la WP_Queryclase.

Rebelde Fénix
fuente
14

Asegúrese de usarlo wp_reset_query()después de usarlo query_posts()porque afectará también el resultado de otra consulta.

Bindiya Patoliya
fuente
10

Si recuerdo haber leído bien, esencialmente "el bucle" está funcionando WP_Queryen los archivos principales, pero de una manera más fácil de entender.

tw2113
fuente
6
  • query_posts () : podría usarse en un solo caso si necesita modificar la consulta principal. Establece muchas variables globales;
  • get_posts () : es muy similar en mecánica y acepta los mismos argumentos, pero devuelve una variedad de publicaciones
  • WP_Query : puede crear y trabajar con su propio objeto. Un poco más complejo, menos restricciones, es seguro de usar en cualquier lugar.
dalveer
fuente
-6

Yo diría que no lo uses get_posts()en un complemento. Impone filtros muy restrictivas en algunos casos (serie de suppress_filters, ignore_sticky_posts, etc.) y debe probablemente sólo ser utilizados en un tema cuando se quiere que se haga algo rápido.

m4olivei
fuente