web-dev-qa-db-ja.com

WP_Query - フィルタするか直接

私のファイル、テンプレート、スクリプト、クエリなどの数が増えているので、それをすべて維持するための優れたシステムが必要です。

私はすべてを整理しておくようにしました:

  • テンプレートに<script>タグがありません
  • 管理オプションから動的に変更される可能性があるCSS変数の場合のみ、PHPをインライン化します。
  • リクエストなどを最小限に抑えるためのJSCSSの単一の大きなファイル

私は少なくとも10個のクエリを持っているので、クエリを整理する時が来ました。

  1. 最初のオプション:各クエリでカスタムのadd_filter()を使う

    • クエリはすべて1つのファイルまたはディレクトリにあるため、クエリを探す必要はありません。
    • 変更する必要がある場合は、1つの場所で変更するだけでよく、すべての異なるテンプレートを変更する必要はありません。
  2. 2番目の選択肢:すべてのクエリをテンプレートに書き込む 通常行われているように

    • 基本的にすべての点が最初の選択肢に反しています

質問:

クエリ引数にfilterを使用することには欠点がありますか?パフォーマンス?他に何か?


例:

  1. いつもの

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

    //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

ここではいくつかのことを考慮する必要がありますが、クエリのパフォーマンスを向上させた後のようです。自問しなければならない最初で最も重要な質問は次のとおりです。

カスタムクエリが必要ですか

しばらく前にこのテーマについて extensive post を実行しました。リンクの私の投稿を読んだ後に上記の質問に「はい」と答えた場合、カスタムクエリを作成するときに次のことを考慮する必要があります。

  • メタ値による順序付けのような複雑なorderby操作を(where you can)避けてください。 SQLは順序付けが最適ではなく、PHPの方が速い場合があります。リソースを節約するために、複雑な順序付けにはusort()を好む傾向があります。リソースのランダムな順序付けも非常に難しい

  • 特別に多くのOR演算子を使用して、重度にネストされたメタクエリと税クエリを使用して複雑なクエリを作成しないでください(where you can)。これらはリソースに関して非常に厳しいです。

  • 生成されたSQLでLIKE演算子を使用しないでください(where you can)。これらも高価です

  • transientsand caches)を使用して、高価なクエリを保存します。ランダムクエリの場合、これを行うことはできないため、この問題に対処するには他の方法を調べる必要があります。

  • 用語のリストを取得し、各用語ごとにカスタムクエリを実行する典型的なforeachループを常に避けてください。これらは本当に高価です。むしろ、すべての投稿を一度だけ照会してから、 usort()を使用して結果をソートします

  • 必要に応じてクエリを作成します。ほとんどの場合、投稿をクエリするだけで、IDを取得して別の関数に渡すことができます。このような場合、投稿IDのみをクエリします。これにより、リソースを大幅に節約できます。クエリ引数に'fields'=>'ids',を追加するだけです

  • ページ分割されていないクエリを高速化するには、get_posts()を使用するか、単に'no_found_rows'=>trueWP_Queryに渡します(これはまさに `get_postsが行うこと)。これにより、ページネーションプロセスがスキップされ、巨大なデータベースのリソースが大幅に節約されます。

これは、クエリを高速化するための何らかのガイドラインとして意図されています。クエリを高速化するために、他にもいくつかのことがあります。

クエリ引数にフィルターを使用すると、欠点がありますか?パフォーマンス?他に何か?

なぜ問題があるのか​​わかりません。商用テーマを作成している場合、あなたは間違いなく正しいです。フィルタリング可能なものを作成すると、子テーマの作成者の生活がはるかに簡単になります。ミリ秒からミリ秒の費用がかかる場合がありますが、間違いなく十分に使用されています。それは衛生のようなものです。サニテーションには時間とリソースがかかります(非常にわずかですが)が、何かにミリ秒を費やすことで、サイトがハッキングされ破壊されるのを防ぐことができます

私見では、ユーザビリティと保守性を損なうことなく、クエリを高速化する他の方法を検討する必要があります。オプション2は間違いなくあなたが商用テーマのためにすべきことです

IDEA(少し船外かもしれません;-)

pre_get_postsを使用して、カスタムクエリをフィルタリングし、フィルタリング可能にすることもできます。クエリで独自のカスタムパラメータを設定するのと同じくらい簡単で、そのパラメータを使用してクエリをターゲットにします

次の例では、数値を与えるカスタムパラメータquery_noを使用します

クエリ

$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
    }
} );

ユーザーは、引数を追加したり、渡された引数を変更したりできるようになりました

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