Saya menemukan masalah aneh.
Katakanlah Anda mengakses url acak, tiga level atau lebih dalam:
http://example.com/a/b/c
http://example.com/a/b/c/d
...
Lalu is_404()
adalah true
. Sejauh ini baik. Tetapi untuk beberapa alasan posting terakhir dipertanyakan.
$wp_query->request
adalah
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
Yang kemudian tentu saja membuat have_posts()
kembali true
dan seterusnya. Adakah yang bisa menjelaskan hal ini?
Apa yang saya temukan sejauh ini:
Alasan yang hanya menendang tiga tingkat atau lebih dalam adalah bahwa sebelum WP mencari posting dan lampiran yang entah bagaimana menghasilkan beberapa perilaku lain.
Tampaknya meskipun WP mengakui permintaan tersebut sebagai 404 pada satu titik, tetapi kemudian mengambil pos terbaru. Dengan bantuan dari @kaiser dan @GM saya telah melacaknya sampai di suatu tempat dari /wp-includes/class-wp.php:608
Jawaban:
Anda mungkin terkejut, tetapi tidak ada yang aneh di sana.
Pertama-tama mari kita perjelas bahwa di WordPress ketika Anda mengunjungi URL frontend Anda memicu kueri. Selalu.
Kueri itu hanya standar
WP_Query
, seperti yang dijalankan melalui:Hanya ada satu perbedaan:
$args
variabel dihasilkan oleh WordPress menggunakanWP::parse_request()
metode ini. Apa yang dilakukan metode itu hanyalah melihat URL, dan pada aturan penulisan ulang, dan mengonversi URL menjadi array argumen.Tetapi apa yang terjadi ketika metode itu tidak dapat melakukannya karena URL tersebut tidak valid? Argumen kueri hanyalah array seperti ini:
(Sumber sini dan sini ).
Jadi array itu diteruskan ke
WP_Query
.Sekarang coba lakukan:
Apakah Anda terkejut bahwa kueri itu persis dengan yang ada di OP? Bukan saya.
Begitu,
parse_request()
membangun sebuah array dengan kunci kesalahanWP_Query
, yang menjalankannyahandle_404()
yang berjalan setelah kueri, melihat'error'
parameter dan setis_404()
ke trueJadi,
have_post()
danis_404()
tidak berhubungan. Masalahnya adalah bahwaWP_Query
tidak memiliki sistem untuk hubungan pendek permintaan ketika ada masalah, jadi setelah objek dibangun, berikan beberapa argumen padanya dan permintaan akan berjalan ...Edit:
Ada 2 cara untuk mengatasi masalah ini:
404.php
templat; WordPress akan memuatnya di 404 URL dan di sana Anda tidak perlu memeriksanyahave_posts()
Paksa
$wp_query
kosong pada 404, sesuatu seperti:sumber
$wp->matched_rule
), tetapi permintaan masih melalui gerakan karena tidak memperhatikan hal itu.WHERE 1=0
dalam sql karena tidak dapat menghentikan permintaan, maka paksa permintaan yang tidak menghasilkan apa-apa ... @Rarstis_404()
.