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本身,和计数器

参考资料

相关推荐
Smile灬凉城6665 小时前
反序列化为啥可以利用加号绕过php正则匹配
开发语言·php
奥顺7 小时前
PHPUnit使用指南:编写高效的单元测试
大数据·mysql·开源·php
黑客Jack9 小时前
网络安全加密
安全·web安全·php
龙哥·三年风水12 小时前
workman服务端开发模式-应用开发-后端api推送修改二
分布式·gateway·php
计算机徐师兄13 小时前
基于TP5框架的家具购物小程序的设计与实现【附源码、文档】
小程序·php·家具购物小程序·家具购物微信小程序·家具购物
希雅不是希望14 小时前
Ubuntu命令行网络配置
网络·ubuntu·php
龙哥·三年风水16 小时前
workman服务端开发模式-应用开发-后端api推送修改一
分布式·gateway·php
开心工作室_kaic1 天前
springboot461学生成绩分析和弱项辅助系统设计(论文+源码)_kaic
开发语言·数据库·vue.js·php·apache
火³可²1 天前
PHP接入美团联盟推广
开发语言·php
奥顺1 天前
PHP与AJAX:实现动态网页的完美结合
大数据·mysql·开源·php