WordPress中手动返回404的优雅方式

这篇文章也可以在我的博客中查看

关于本文

WordPress虽然有比较完善的404处理机制,但有时候我们需要手动返回404,这篇文章就来探讨一下这个问题。

何时返回404

根据mdn,404用作示意客户端找不到相应的资源,这可能是:

  • 资源不存在
  • 资源不应该被访问
    • 与403相比:403指的是可被访问但强调用户"无权"

第一种情况WordPress会为我们处理,但第二种情况,往往需要我们手动驳回

Core是怎么做的?

先来看看WordPress Core是怎么做的,方便抄作业

在class-wp.php中的handle_404()中可以看到以下逻辑:

随版本更新文件和函数内容可能有变,此是2023-8-12的内容

php 复制代码
handle_404()
{
	...
	$wp_query->set_404();
	status_header( 404 );
	nocache_headers();
	...
}
  1. 首先使用全局变量$wp_query设置404
  2. 然后设置响应头代码为404
  3. 最后设置响应头为:不添加缓存处理(no-cache-headers)
  • 它会将Cache-Control从响应头中移除

所以入乡随俗,我们也应该这么做

远古做法

在WordPress Hook还没成熟之前,习惯在WordPress处理完404之后的第一个钩子继续进行404处理

因此会选择在'wp'钩子手动返回404:

php 复制代码
add_action('wp', function () {
    if (/* contidtion */) {
        global $wp_query;
        $wp_query->set_404();
        status_header(404);
		nocache_headers();
    }
});

nocache_headers()是可选的,但core做了,我就跟着做了

新做法

后来WordPress给了一个pre_handle_404,在WordPress本身的handle_404()真正执行之前

这个filterhook需要返回一个单值:

  • 为false时继续执行handle_404()
  • 否则将短路handle_404()的执行

这给了我们一个手动处理404的机会

php 复制代码
add_filter('pre_handle_404', function ($_, $wp_query) {
    if (/* contidtion */) {
        //设置404
        $wp_query->set_404();
        status_header(404);
        nocache_headers();
    }
    return false;
}, 10, 2);

至于是否需要短路handle_404()的执行

就我们这个例子而言不需要

因为我们手动设置了404,而handle_404()会在已经是404的情况下自动短路

因此无论是return false还是return其它,handle_404()都不会执行

问题修复

阴差阳错之间让我发现一个小问题

如果在主查询有结果的情况下(have_posts() === true)返回404,整个主循环(main loop)还是有效的,但事实上我们返回错误时不希望主循环生效,因此我们可以考虑手动清空主循环:

php 复制代码
add_filter('pre_handle_404', function ($_, $wp_query) {
    if (/* contidtion */) {
        //清空文章
        $wp_query->posts = [];
        unset($wp_query->post);
        $wp_query->post_count = 0;
		
        //设置404
        $wp_query->set_404();
        status_header(404);
        nocache_headers();
    }
    return false;
}, 10, 2);

主要是清空了posts本身,和计数器

参考资料

相关推荐
李纲明14 小时前
WordPress 后台登录马上被踢回登录页:Cookie 域、HTTPS、盐值和页面缓存怎么查
运维·缓存·https·php·wordpress·cookie
4SAPI14 小时前
AI 数据分析工具大模型 API 选型指南
大数据·人工智能·架构·php·1024程序员节
f89790707015 小时前
php升级之后切换到php8.2.35报pdo错误
php
4SAPI15 小时前
搭建 AI 数据分析工具大模型 API 选型指南
数据库·人工智能·架构·php·1024程序员节
Regentsoft丽晶软件16 小时前
从 “定时拉取“ 到 “事件驱动“,服装库存实时同步的底层架构怎么设计?
经验分享·php·零售
用户609686242660819 小时前
页面构建器做的页面翻译:短代码、区块、动态内容各自会踩什么坑
php·wordpress
阿文和她的Key19 小时前
PHP2Shell事故四层拆解:AI找洞是小时级,披露协调还是邮件级
网络·人工智能·架构·php
贵州诚鑫致达科技有限公司1 天前
PHP两个9.2分RCE漏洞,速查版本
服务器·php·1024程序员节
hudie7651 天前
LikeShop 二开最常改的 5 个文件(附改前改后对比)
前端·uni-app·php·个人开发
东宇科技1 天前
crmeb开源版本安装步骤2026-10-20
后端·php·crmeb