web-dev-qa-db-fra.com

WP_Query - filtrer ou directement?

Le nombre de mes fichiers, modèles, scripts, requêtes, etc. est en train de grandir et j'ai besoin d'un bon système pour tout gérer.

J'ai essayé de tout organiser:

  • Pas de balises <script> dans les modèles
  • Inline CSS uniquement lorsqu'il s'agit de la variable PHP qui peut être modifiée de manière dynamique à partir des options d'administration
  • Un seul gros fichier de JS et CSS pour minimiser les demandes, etc.

Il est maintenant temps d'organiser mes requêtes car j'en ai au moins 10 et le nombre ne cesse d'augmenter.

  1. Première option: utiliser custom add_filter() avec chaque requête

    • Je n'ai pas à rechercher les requêtes car elles sont toutes dans un seul fichier ou répertoire
    • Si j'ai besoin de le changer, je n'ai besoin de le changer que dans un seul endroit, pas dans tous mes modèles.
  2. Seconde option: écrire toutes les requêtes dans les templates comme d'habitude

    • Fondamentalement, chaque point est au contraire de la première option

Question:

L'utilisation d'un filtre pour les arguments de requête présente-t-elle des inconvénients? Performance? Autre chose?


Exemple:

  1. Habituel:

    $args = array(
    
            'post_type'         => 'my-post',
            'posts_per_page'    => 8,
            'orderby'           => 'Rand', 
        );
    
    }
    
    $results = new WP_Query( $args );
    
  2. Filtre:

    //In one file -> easy to find and change
    add_filter( 'some_args', 'some_search_args' );
    
    function some_search_args( $search_args ) {
    
        $search_args['post_type'] = 'property';
        $search_args['posts_per_page'] = 8;
        $search_args['orderby'] = 'Rand';
    
        //All kinds of logic and conditional code to here
    
        return $search_args;
    }
    
    
    //And
    
    
    //Just include like this to any template you want and as many as you want
    //To change the query, you'll just have to change to code above
    $search_args = array();
    $search_args = apply_filters( 'some_args', $search_args );
    
    $results = new WP_Query( $search_args );
    
4
N00b

Vous devez considérer un certain nombre de choses ici et il semble que vous soyez après avoir augmenté les performances d'une requête. La première et la plus importante question que vous devez vous poser est la suivante:

Ai-je besoin d'une requête personnalisée

J'ai fait un vaste post sur ce sujet il y a quelque temps que vous devriez vérifier. Si vous avez répondu oui à la question ci-dessus après avoir lu mon message dans le lien, vous devez tenir compte des éléments suivants lors de la création de requêtes personnalisées.

  • Évitez les opérations (si vous le pouvez} _) complexes orderby telles que le tri par méta-valeurs. SQL n'est pas le meilleur pour commander et PHP est parfois plus rapide. J'ai tendance à préférer usort() pour les commandes complexes afin d'économiser des ressources. Ordre aléatoire est également très dur sur les ressources

  • Évitez (lorsque cela est possible} _) de créer des requêtes complexes avec des requêtes de méta et de taxe fortement imbriquées, spécialement avec un grand nombre d'opérateurs OR. Ce sont assez difficiles sur les ressources.

  • Évitez (si possible _) d’utiliser des opérateurs LIKE dans votre code SQL généré. Ce sont aussi chers

  • Utilisez transitoires (et caches _) pour stocker des requêtes coûteuses. Pour des requêtes aléatoires, vous ne pouvez pas le faire, vous devrez donc rechercher d'autres méthodes pour résoudre ce problème.

  • Évitez toujours la boucle foreach typique dans laquelle vous obtenez une liste de termes, puis en exécutant une requête personnalisée pour chaque terme, ils sont vraiment coûteux. Interrogez plutôt toutes les publications et utilisez une fois/ usort() pour trier les résultats

  • Créez une requête en fonction de vos besoins. La plupart du temps, nous n'avons besoin d'interroger que les publications pour que leurs identifiants soient transmis à une autre fonction. Dans de tels cas, interrogez uniquement les ID de publication. Cela économise vraiment beaucoup de ressources. Ajoutez simplement 'fields'=>'ids', à vos arguments de requête

  • Pour accélérer les requêtes non paginées, utilisez get_posts() ou passez simplement 'no_found_rows'=>true à WP_Query (c'est exactement ce que `get_posts fait} _). Cela saute le processus de pagination et économise beaucoup de ressources sur des bases de données énormes.

Ceci est simplement conçu comme une sorte de guide pour accélérer la requête. Il y a encore d'autres choses pour accélérer les requêtes.

L'utilisation d'un filtre pour les arguments de requête présente-t-elle des inconvénients? Performance? Autre chose?

Je ne vois pas pourquoi il pourrait y avoir des problèmes. Si vous créez un thème commercial, vous êtes certainement en train de le faire correctement. Rendre quelque chose filtrable facilite beaucoup la vie des auteurs de thèmes pour enfants. Cela peut coûter un millième de millième de seconde, mais le temps est certainement bien utilisé. C'est comme l'assainissement. L’assainissement coûte du temps et des ressources (bien que ce soit très très peu), mais dépenser une milliseconde de plus sur quelque chose peut sauver votre site d’être piraté et détruit

IMHO, vous auriez besoin de rechercher d'autres moyens d'accélérer une requête et de ne pas compromettre l'utilisabilité et la maintenabilité. L'option 2 est certainement quelque chose que vous devriez faire pour les thèmes commerciaux

IDEA (peut-être un peu trop fort ;-))

Vous pouvez également utiliser pre_get_posts pour filtrer votre requête personnalisée et la rendre filtrable. C'est aussi simple que de définir votre propre paramètre personnalisé dans votre requête et qu'ils l'utilisent pour cibler votre requête.

Dans l'exemple suivant, nous allons utiliser un paramètre personnalisé query_no auquel nous donnerons des valeurs numériques

Les requêtes

$q1 = new WP_Query( ['query_no' => 1] );    
$q2 = new WP_Query( ['query_no' => 2] );    
$q3 = new WP_Query( ['query_no' => 3] );    

pre_get_posts

add_action( 'pre_get_posts', function( $q ) 
{
    if ( $q->get( 'query_no' ) == 1 ) {
        $q->set( 'posts_per_page', -1 );
        // Add any other extra arguments to set
    }

    if ( $q->get( 'query_no' ) == 2 ) {
        $q->set( 'post_type', ['post', 'page'] );
        // Add any other extra arguments to set
    }

    if ( $q->get( 'query_no' ) == 3 ) {
        $q->set( 'post_status', 'trash' );
        // Add any other extra arguments to set
    }
} );

L'utilisateur peut maintenant ajouter des arguments supplémentaires ou modifier celui passé

add_action( 'pre_get_posts', function( $q ) 
{
    if ( $q->get( 'query_no' ) == 2 ) {
        // Lets add another post type
        $post_types = $q->get( 'post_type' );
        $post_types = array_merge( $post_types, ['my_post_type'] );

        $q->set( 'post_type'     , $post_types );
        $q->set( 'posts_per_page', -1          );
        // Add any other extra arguments to set
    }

}, 
11 // Make sure this runs after the default action
); 
4
Pieter Goosen