Quand devriez-vous utiliser WP_Query vs query_posts () vs get_posts ()?

390

Il semble que la moitié des didacticiels du Codex et de la blogosphère utilisent query_posts() et la moitié d’entre elles WP_Query . Quel est le problème?

    
posée Dan Gayle 13.09.2010 - 17:58
la source

8 réponses

629
  • query_posts() est une façon trop simpliste et problématique de modifier la requête principale d'une page en la remplaçant par nouvelle instance de la requête. Il est inefficace (ré-exécute les requêtes SQL) et échouera carrément dans certaines circonstances (particulièrement lorsqu'il s'agit de pagination de messages). Tout code WP moderne devrait utiliser des méthodes plus fiables, comme utiliser pre_get_posts , pour cela. TL; DR ne jamais utiliser query_posts () ;

  • get_posts() a un usage très similaire et accepte les mêmes arguments (avec certaines nuances, comme différentes valeurs par défaut). ), mais retourne un tableau d'articles, ne modifie pas les variables globales et peut être utilisé n'importe où;

  • La classe WP_Query alimente les coulisses, mais vous pouvez également créer et utiliser votre propre objet. de cela. Un peu plus complexe, moins de restrictions, également sûr à utiliser n'importe où.

    
réponse donnée Rarst 13.09.2010 - 18:10
la source
52

query_posts - Vous ne devriez jamais utiliser query_posts . Mis à part ce que @Rarst a dit, le gros problème de query_posts est qu'il casse l'objet de requête principal (stocké dans $wp_query ). Un grand nombre de plugins et de code personnalisé reposent sur l'objet de requête principal. Par conséquent, le fait de casser l'objet de requête principal signifie que vous cassez les fonctionnalités des plugins et du code personnalisé. Une de ces fonctions est la très importante fonction de pagination. Si vous cassez la requête principale, vous cassez la pagination.

Pour prouver l’état de query_posts , procédez comme suit pour tous les modèles et comparez les résultats

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

get_posts et WP_Query sont le moyen approprié de créer des requêtes secondaires ( telles que les publications, les curseurs, le contenu vedette et le contenu des pages de couverture statiques ) avec. Il convient de noter que vous ne devez utiliser aucun des deux en faveur de la requête principale sur la page d'accueil, une page unique ou tout type de page d'archive, car cela casserait la fonctionnalité de la page. Si vous devez modifier la requête principale, utilisez pre_get_posts pour le faire et non une requête personnalisée. ( UPDATE: pour les pages de couverture statiques et les pages de référence, voir Utilisation de pre_get_posts sur les pages vraies et les pages de garde statiques *)

Essentiellement, WP_Query est utilisé par la requête principale et par get_posts . Cependant, bien que get_posts() utilise WP_Query , il existe quelques différences

  • get_posts sont plus rapides que WP_Query . La marge dépend du nombre total de messages du site. La raison en est que get_posts passe 'no_found_rows' => true par défaut à WP_Query qui saute / rompt légalement la pagination. Avec 'no_found_rows' => true , WP_Query récupère le nombre de messages demandés, puis se désiste, puis recherche par défaut tous les messages correspondant à la requête afin de calculer la pagination.

    Pour cette raison, get_posts() devrait être utilisé uniquement pour les requêtes non paginées. Paginer get_posts est vraiment un gros bazar. WP_Query doit être utilisé pour toutes les requêtes paginées

  • get_posts() ne sont pas influencés par les filtres posts_*WP_Query est influencé par ces filtres. La raison en est que get_posts , par défaut, passe de 'suppress_filters' => true à WP_Query

  • get_posts a quelques paramètres supplémentaires tels que include , exclude , numberposts et category . Ces paramètres sont modifiés en paramètres valides pour WP_Query avant d’être passés à WP_Query . include est converti en post__in , exclude en post__not_in , category en cat et numberposts en posts_per_page . Juste une note, tous les paramètres pouvant être passés à WP_Query fonctionnent avec get_posts , vous pouvez ignorer et ne pas utiliser les paramètres par défaut de get_posts

  • get_posts ne renvoie que la propriété $posts de WP_Query tandis que WP_Query renvoie l'objet complet. Cet objet est très utile quand il s’agit de conditionnelles, de pagination et d’autres informations utiles pouvant être utilisées dans la boucle.

  • get_posts n'utilise pas la boucle, mais une boucle foreach pour afficher les publications. En outre, aucune balise de modèle n'est disponible par défaut. setup_postdata( $post ) doit être utilisé pour rendre les balises de modèle disponibles. WP_Query utilise la boucle et les balises de modèle sont disponibles par défaut

  • get_posts passe 'ignore_sticky_posts' => 1 à WP_Query , donc get_posts ignore par défaut les posts collants

Sur la base de ce qui précède, il vous appartient de choisir get_posts ou WP_Query et avez-vous besoin de la requête? Ce qui précède devrait vous guider dans votre choix

    
réponse donnée Pieter Goosen 18.06.2015 - 19:46
la source
29

La différence fondamentale est que query_posts() ne sert en réalité qu'à modifier la boucle en cours. Une fois que vous avez terminé, il est nécessaire de réinitialiser la boucle et de l’envoyer en joyeux chemin. Cette méthode est aussi un peu plus facile à comprendre, tout simplement parce que votre "requête" est essentiellement une chaîne d’URL que vous transmettez à la fonction, comme suit:

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

D'autre part, WP_Query est plus un outil à usage général, et ressemble plus à l'écriture directe de requêtes MySQL que query_posts() . Vous pouvez également l'utiliser n'importe où (pas seulement dans la boucle) et cela n'interfère en aucun cas avec les requêtes de publication en cours d'exécution.

J'ai tendance à utiliser WP_Query plus souvent, comme cela arrive. Vraiment, cela dépendra de votre cas particulier.

    
réponse donnée nickmjones 13.09.2010 - 18:09
la source
13

Il n’est tout simplement pas nécessaire d’utiliser query_posts() . Tout ce qu'il fait, c'est instancier un nouvel objet WP_Query et le réaffecter à global wp_query .

Pour référence, voici la fonction réelle query_posts() .

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

Instanciez votre propre objet WP_Query si vous souhaitez créer un script de requête personnalisé approfondi. Ou utilisez get_posts() si tout ce que vous avez à faire est une légère manipulation ici et là.

Dans les deux cas, je vous recommande vivement de vous rendre un service, d'aller à wp_includes/query.php et de parcourir la classe WP_Query .

    
réponse donnée RebelPhoenix 13.07.2013 - 18:38
la source
13

Assurez-vous d'utiliser wp_reset_query() après avoir utilisé query_posts() , car cela affectera également le résultat de la requête.

    
réponse donnée Bindiya Patoliya 08.07.2013 - 06:50
la source
9

Si je me souviens bien d'avoir lu, "la boucle" correspond essentiellement à WP_Query dans les fichiers core, mais d'une manière plus compréhensible.

    
réponse donnée tw2113 23.09.2010 - 22:21
la source
5
  • query_posts () : peut être utilisé dans un seul et même cas si vous devez modifier la requête principale. Il définit beaucoup de variables globales;
  •   
  • get_posts () : la mécanique est très similaire et accepte les mêmes arguments, mais renvoie un tableau de messages
  •   
  • WP_Query : vous pouvez créer et utiliser son propre objet. Un peu plus complexe, moins de restrictions, il est sûr de l’utiliser n'importe où.
réponse donnée dalveer 19.07.2017 - 16:28
la source
-5

Je dirais que n'utilisez pas get_posts() dans un plugin. Il impose des filtres très restrictifs dans certains cas ( suppress_filters , ignore_sticky_posts , etc. du jeu) et ne devrait probablement être utilisé dans un thème que si vous voulez que quelque chose soit fait rapidement.

    
réponse donnée m4olivei 25.09.2013 - 18:03
la source

Lire d'autres questions sur les étiquettes