問題描述
我遇到了一個奇怪的問題。
說你訪問一個隨機 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 等等。有人可以解釋一下嗎
我發現到目前為止
只有三點或更多級別深入的原因是,在 WP 查詢帖子和附件之前,這些結果會導致其他一些行為。
似乎即使 WP 在一點上將該請求識別為 404,然後獲取最新的帖子。在 @kaiser 和 @G.M. 的幫助下,我已經將其跟蹤到了/wp-includes/class-wp.php:608 的某個地方
最佳解決方案
你可能會驚訝,但沒有什麼奇怪的。
首先讓我們澄清一下,在 WordPress 中,當您訪問前端 URL 時,您將觸發查詢。總是。
該查詢只是一個標準的 WP_Query,就像透過以下方式執行的那樣:
$query = new WP_Query( $args );
只有一個區別:$args 變數由 WordPress 使用 WP::parse_request()方法生成。該方法的作用是檢視 URL,並重寫規則,並將 URL 轉換為引數陣列。
但是,由於 URL 是 non-valid,那個方法不能做到這一點呢?查詢 args 只是一個這樣的陣列:
array( 'error' => '404' );
所以將該陣列傳遞給 WP_Query 。
現在嘗試做:
$query = new WP_Query( array( 'error' => '404' ) );
var_dump( $query->request );
您是否驚訝於查詢完全是 OP 中的查詢?我不是。
所以,
-
parse_request()構建一個帶有錯誤鍵的陣列 -
該陣列被傳遞給
WP_Query,它只是執行它 -
在查詢後執行的
handle_404(),檢視'error'引數,並將is_404()設定為 true
所以 have_post()和 is_404()是無關的。問題是 WP_Query 在出現錯誤時沒有向 short-circuit 詢問系統,所以一旦物件被建立,傳遞一些引數就可以執行查詢。
編輯:
有兩種方法來克服這個問題:
-
建立
404.php模板; WordPress 將載入 404 網址,您不需要檢查have_posts() -
強制
$wp_query在 404 上為空,類似於:add_action( 'wp', function() { global $wp_query; if ( $wp_query->is_404() ) { $wp_query->init(); $wp_query->is_404 = true; // init() reset 404 too } } );
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。