Me deparei com uma questão estranha.
Digamos que você acesse um URL aleatório, com três ou mais níveis de profundidade:
http://example.com/a/b/c
http://example.com/a/b/c/d
...
Então is_404()
é true
. Por enquanto, tudo bem. Mas, por algum motivo, as últimas postagens são consultadas.
$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
O que, é claro, faz have_posts()
retorno true
e assim por diante. Alguém pode explicar isso?
O que eu descobri até agora:
A razão pela qual apenas entra em ação em três ou mais níveis é que, antes disso, o WP procura por postagens e anexos que de alguma forma resultam em algum outro comportamento.
Parece que, embora o WP reconheça a solicitação como 404 em um ponto, ele busca as postagens mais recentes. Com a ajuda do @kaiser e do @GM , localizei isso em algum lugar de /wp-includes/class-wp.php:608
Respostas:
Você pode se surpreender, mas não há nada de estranho lá.
Antes de tudo, vamos esclarecer que no WordPress, quando você visita um URL de front-end, aciona uma consulta. Sempre.
Essa consulta é apenas um padrão
WP_Query
, assim como as executadas por:Há apenas uma diferença: as
$args
variáveis são geradas pelo WordPress usando oWP::parse_request()
método O que esse método faz é apenas olhar para o URL e as regras de reescrita e converter o URL em uma matriz de argumentos.Mas o que acontece quando esse método não é capaz de fazer isso porque o URL não é válido? Os argumentos da consulta são apenas uma matriz como esta:
(Fonte aqui e aqui ).
Portanto, essa matriz é passada para
WP_Query
.Agora tente fazer:
Você está surpreso que a consulta seja exatamente a do OP? Eu não sou.
Então,
parse_request()
cria uma matriz com uma chave de erroWP_Query
, que apenas a executahandle_404()
executado após a consulta, analisa o'error'
parâmetro e defineis_404()
como trueEntão,
have_post()
eis_404()
não estão relacionados. O problema é queWP_Query
não há um sistema que provoque um curto-circuito na consulta quando algo der errado. Assim que o objeto for criado, passe alguns argumentos para ela e a consulta será executada ...Editar:
Existem 2 maneiras de superar esse problema:
404.php
modelo; O WordPress carregará isso em 404 URLs e você não precisará procurarhave_posts()
Forçar
$wp_query
a ficar vazio no 404, algo como:fonte
$wp->matched_rule
), mas a consulta ainda está sendo processada porque não presta atenção a isso.WHERE 1=0
no SQL porque não pode parar a consulta para forçar uma consulta que retorno nada ... @Rarstis_404()
verificação adicional .