一部の404でループが空にならないのはなぜですか?


10

私は奇妙な問題に出くわしました。

3レベル以上の深さのランダムなURLにアクセスするとします。

http://example.com/a/b/c
http://example.com/a/b/c/d
...

次にis_404()ですtrue。ここまでは順調ですね。しかし、何らかの理由で最後の投稿が照会されます。

$wp_query->request

です

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
    FROM wp_posts 
    WHERE 1=1 
        AND wp_posts.post_type = 'post' 
        AND (
            wp_posts.post_status    = 'publish' 
            OR wp_posts.post_status = 'private'
            ) 
    ORDER BY wp_posts.post_date DESC 
    LIMIT 0, 5

そして、もちろんそれはhave_posts()戻っtrueてきます。誰かがこれを説明できますか?

これまでにわかったこと:

3つ以上のレベルでのみキックインする理由は、そのWPがその前に投稿と添付ファイルを検索するため、何らかの形で他の動作が発生するためです。

WPがリクエストをある時点で404として認識したとしても、最新の投稿をフェッチするようです。@kaiserおよび@GMの助けを借りて、これ/wp-includes/class-wp.php:608からどこかに追跡しました


ページのコードを追加していない場合はあなたを助けるために難しいことつもりである
トマス・コット

3
これは私のコードに固有のものではありません。すべてのデフォルトのテーマを備えたまったく新しいインストールでも同様に動作します。
クラフトナー2014

カスタムテーマが機能しない場合、少なくとも1つのテーマに名前を付けることができますか?特定のパラメータを使用していますか?あなたはナメクジを変えましたか?どのバージョンのWPを使用していますか?
トマス・コット

本当に。ただし、必要に応じて、Twenty Elevenを試してください。
クラフトナー、2014

すべての質問で申し訳ありませんが、投稿が表示されていると思いました。
トマス・コット

回答:


9

驚くかもしれませんが、そこには奇妙なことは何もありません。

まず、WordPressでフロントエンドURLにアクセスしたときにクエリがトリガーされることを明確にしましょう。常に。

そのクエリはWP_Query、次のように実行されるクエリと同じように、単なる標準です。

$query = new WP_Query( $args );

唯一の違いがあり$argsます。変数は、WP::parse_request()メソッドを使用してWordPressによって生成されます。このメソッドが行うことは、URLと書き換えルールを見て、URLを引数の配列に変換することです。

しかし、URLが無効であるためにそのメソッドがそれを実行できない場合はどうなりますか?クエリ引数は、次のような単なる配列です。

array( 'error' => '404' );

ここここに出典)。

その配列はに渡されWP_Queryます。

今やってみてください:

$query = new WP_Query( array( 'error' => '404' ) );
var_dump( $query->request );

クエリがOPのクエリとまったく同じであることに驚いていますか?私は違います。

そう、

  1. parse_request() エラーキーを持つ配列を構築します
  2. その配列はに渡されWP_Query、実行されます
  3. handle_404()実行その、クエリ、見'error'パラメータとのセットis_404()をtrueに

だから、have_post()is_404()関連していません。問題は、WP_Query何か問題が発生したときにクエリを短絡させるシステムがないため、オブジェクトが作成されたら、それに引数を渡すとクエリが実行されます...

編集:

この問題を解決するには2つの方法があります。

  • 404.phpテンプレートを作成します。WordPressは404のURLでそれをロードし、そこで確認する必要はありませんhave_posts()
  • $wp_query404で強制的に空にする:

    add_action( 'wp', function() {
        global $wp_query;
        if ( $wp_query->is_404() ) {
            $wp_query->init();
            $wp_query->is_404 = true; // init() reset 404 too
        }
    } );
    

4
これが通常発生しない理由は、404は通常クエリの結果であるためです。ただし、この場合は、一致しない書き換えルール$wp->matched_rule)の結果ですが、クエリはそれに注意を払っていないため、まだモーションを通過しています。
Rarst

+1。はい、クエリはそれに注意を払いません。現在のコードで、それを停止する方法がないため、注意を払うことができません。例としてWHERE 1=0、クエリを停止できないためにSQLで設定されたWordPressセットに無効な分類がクエリされると、何も返さないクエリを強制します... @Rarst
gmazzap

わかりました。わかりました。したがって、残っている本当の問題は、WP_Queryが何も返さない場合に合理的な引数が渡されない場合にWP_Queryがデフォルトのクエリの投稿を取得するのはなぜ意味があるのか​​ということです。
クラフトナー2014

2
@kraftnerによると、WordPressはクエリの実行を回避できないため、適切な引数がない場合は2つの選択肢があります。確かに何も返さないクエリを実行する(無効な分類がクエリされた場合など)、デフォルトのクエリを実行する。なぜこの場合にWPが後者を選択するのかは、コア
開発者に

@TomásCotもちろん、失敗しても本当に失敗して完全に無関係なものを返さないようにしたいです。とにかく、物事は今は片付けられ、私は追加のis_404()チェックを行う必要があります。
クラフトナー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.