web-dev-qa-db-fra.com

Quand faut-il utiliser WP_Query vs query_posts () vs get_posts ()?

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

412
Dan Gayle
  • query_posts() est trop simpliste et constitue un moyen problématique de modifier la requête principale d'une page en la remplaçant par une 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 publications). Tout code WP moderne devrait utiliser des méthodes plus fiables, telles que l'utilisation du pre_get_posts hook, à cette fin. TL; DR ne pas utiliser query_posts () ever .

  • get_posts() est très similaire dans son utilisation et accepte les mêmes arguments (avec quelques nuances, comme différentes valeurs par défaut), mais renvoie un tableau de publications, ne modifie pas les variables globales et peut être utilisé n’importe où.

  • WP_Query est la classe qui active les deux dans les coulisses, mais vous pouvez également créer et travailler avec votre propre instance. Un peu plus complexe, moins de restrictions, également sûr à utiliser n'importe où.

  

658
Rarst

query_posts - Vous ne devriez jamais utiliser query_posts. Mis à part ce que @Rarst a dit, le très gros problème avec query_posts est de casser 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 la gravité 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 la manière correcte de construire secondary queries (comme les messages liés, les curseurs, le contenu en vedette et contenu sur les premières pages 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 garde statiques et les pages vraies, voir Utilisation de pre_get_posts sur les pages vraies et les pages de garde statiques *)

WP_Query est essentiellement utilisé par la requête principale et par get_posts, 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/interdit la pagination. Avec 'no_found_rows' => true, WP_Query récupère le nombre de publications interrogées, puis se désiste. Par défaut, il recherche davantage toutes les publications correspondant à la requête afin de calculer la pagination.

    Pour cette raison, get_posts() doit ê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, transmet '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 devient post__in, exclude en post__not_in, category en cat et numberposts en posts_per_page. Juste une note, all des paramètres pouvant être passés à WP_Query fonctionne avec get_posts, vous pouvez ignorer et ne pas utiliser les paramètres par défaut de get_posts

  • get_posts renvoie uniquement 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 conditions, 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

En fonction de ce qui précède, vous devez utiliser get_posts ou WP_Query et avez-vous besoin de la requête? Ce qui précède devrait vous guider dans votre choix

60
Pieter Goosen

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, simplement parce que votre "requête" est essentiellement une chaîne d’URL que vous transmettez à la fonction, comme ceci:

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 qu'à query_posts(). Vous pouvez également l'utiliser n'importe où (pas seulement dans la boucle) et cela n'interfère pas avec les requêtes post en cours d'exécution.

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

31
nickmjones

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

Pour référence, voici la fonction 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é détaillé. 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 une faveur et d'aller à wp_includes/query.php et de parcourir la classe WP_Query.

15
RebelPhoenix

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

14
Bindiya Patoliya

Si je me souviens de bien lire, "the loop" fait essentiellement WP_Query dans les fichiers core, mais de manière plus compréhensible.

10
tw2113
  • query_posts () : peut être utilisé dans un seul et même cas si vous devez modifier une requête principale. Cela définit beaucoup de variables globales;
  • get_posts () : il est très similaire en mécanique et accepte les mêmes arguments, mais retourne un tableau de publications
  • WP_Query : vous pouvez créer et travailler avec son propre objet. Un peu plus complexe, moins de restrictions, il est sûr de l’utiliser n'importe où.
6
dalveer