在开发WordPress后台程序的时候,有时候会遇到headers already sent的问题,很多时候是因为我们在PHP发送了HTTP header之后又使用了wp_redirect函数来跳转页面,而wp_redirect函数也是通过发送HTTP Header给浏览器来实现的页面跳转。
headers already sent问题产生的原因
我们知道,在同一个http请求中,只能发送一个http head给浏览器,所以有了前面已经发送的 HTTP header,wp_redirect函数再发送 HTTP Header 请求浏览器肯定是收不到了。而在HTTP协议中,发出去的请求就像泼出去的水,是不能修改的,为了让我们及时发现这个问题,进而解决这个问题,PHP运行时就会警告我们说这里有问题,让我们检查。
而这个问题不是致命错误,只会导致一部分程序无效,所以即便我们不解决,直接关掉警告显示也是可以的,但是作为一个负责人的程序员,即便是警告级别的错误,我们也要给他解决掉,确保程序能准确执行。
怎么解决 header already sent 的问题
为了使用页面跳转,我们只能提前发送header请求给浏览器。我们来看一段代码,下面的代码挂载到了 admin_init hook上,在WordPress管理界面初始化后执行,代码主要的作用是判断了当前的页面和操作类型,如果操作类型满足了一定的条件,就执行一些数据处理和跳转操作。
欢迎访问秀主题博客,分享简单实用WP教程add_action('admin_init', function ()
{
if (isset($_GET[ 'page' ]) && $_GET[ 'page' ] === 'list_serial' && isset($_GET[ 'action' ]) && $_GET[ 'action' ] === 'delete') {
$ids = isset($_GET[ 'serial' ]) ? (array)$_GET[ 'serial' ] : [];
$sendback = remove_query_arg(['trashed', 'untrashed', 'deleted', 'locked', 'ids'], wp_get_referer());
wp_redirect(add_query_arg(['trashed' => count($ids), 'ids' => join('_', (array)$ids), 'locked' => 1], $sendback));
exit;
}
});
这段代码是从一个使用 WP_List_Table 类创建的页面中摘出来的,是从列出中删除某些数据后,再跳转回数据列表页面然后显示删除成功的一个操作。WP_List_Table 执行的时候,页面已经初始化了,再执行 WP_List_Table 中的数据删除方法的时候,HTTP header 肯定已经发送了,如果在这个类中实现删除后跳转的操作,就会遇到 header already sent 的警告。所以我们需要跳出这个类,在页面初始化之前就来判断页面的操作以及是否需要跳转。
上面的代码是在WordPress管理后台的操作,在WordPress前台,也会遇到这样的问题,可以参考上面的代码来解决,把hook换成前台页面初始化的hook即可。