Je suis tombé sur un problème étrange.
Supposons que vous accédez à une URL aléatoire, à trois niveaux ou plus de profondeur:
http://example.com/a/b/c
http://example.com/a/b/c/d
...
Alors is_404()
est true
. Jusqu'ici tout va bien. Mais pour une raison quelconque, les derniers messages sont interrogés.
$wp_query->request
est
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
Ce qui fait alors bien sûr le have_posts()
retour true
et ainsi de suite. Quelqu'un peut-il expliquer cela?
Ce que j'ai découvert jusqu'à présent:
La raison qui ne se déclenche qu'à trois niveaux ou plus est qu'avant que WP recherche les publications et les pièces jointes, ce qui entraîne en quelque sorte un autre comportement.
Il semble que même si WP reconnaît la demande comme un 404 à un moment donné, il récupère ensuite les messages les plus récents. Avec l'aide de @kaiser et @GM, je l'ai retrouvé quelque part dans /wp-includes/class-wp.php:608
Réponses:
Vous pourriez être surpris, mais il n'y a rien d'étrange là-bas.
Tout d'abord, clarifions que dans WordPress lorsque vous visitez une URL frontale, vous déclenchez une requête. Toujours.
Cette requête est juste une norme
WP_Query
, tout comme celles exécutées via:Il n'y a qu'une seule différence: les
$args
variables sont générées par WordPress en utilisant laWP::parse_request()
méthode. Cette méthode ne fait que regarder l'URL et les règles de réécriture et convertir l'URL en un tableau d'arguments.Mais que se passe-t-il lorsque cette méthode n'est pas en mesure de le faire car l'URL n'est pas valide? La requête args est juste un tableau comme celui-ci:
(Source ici et ici ).
Donc, ce tableau est passé à
WP_Query
.Essayez maintenant de faire:
Êtes-vous surpris que la requête soit exactement celle d'OP? Je ne suis pas.
Donc,
parse_request()
construit un tableau avec une clé d'erreurWP_Query
, qui l'exécute simplementhandle_404()
qui s'exécute après la requête, examine le'error'
paramètre et prendis_404()
la valeur trueDonc,
have_post()
etis_404()
ne sont pas liés. Le problème est qu'ilWP_Query
n'a pas de système pour court-circuiter la requête en cas de problème, donc une fois l'objet construit, passez-lui quelques arguments et la requête s'exécutera ...Éditer:
Il existe 2 façons de résoudre ce problème:
404.php
modèle; WordPress chargera cela sur 404 URL et là, vous n'avez pas à vérifierhave_posts()
Forcer
$wp_query
à être vide sur 404, quelque chose comme:la source
$wp->matched_rule
), mais la requête passe toujours par les mouvements car elle n'y prête pas attention.WHERE 1=0
dans SQL car il ne peut pas arrêter la requête, alors forcez une requête qui ne renvoie rien ... @Rarstis_404()
vérification supplémentaire .