WordPress后台开发遇到headers already sent警告的解决办法

文 / @WordPress主题

关于headersalreadysent问题的解决

我在开发WordPress后台程序的时候,遇到了headersalreadysent的问题。经过一番调查和研究,我发现这个问题通常是由我们在PHP发送了HTTPheader之后,又使用wp_redirect函数来跳转页面所致。因为wp_redirect函数也是通过发送HTTPHeader给浏览器来实现的页面跳转。

headersalreadysent问题产生的原因

我们都知道,在同一个http请求中,只能发送一个httphead给浏览器。因此,如果先发送了HTTPheader,那么wp_redirect函数再发送HTTPHeader请求给浏览器,浏览器肯定是收不到了。在HTTP协议中,发出去的请求就像泼出去的水,是无法修改的。因此,为了让我们及时发现这个问题,进而解决这个问题,PHP运行时就会警告我们说这里有问题,让我们检查。

请注意,这个问题并不致命,只会导致一部分程序无效。因此,即便我们不解决这个问题,直接关掉警告显示也是可以的。但是作为一个负责人的程序员,即便是警告级别的错误,我们也要给他解决掉,确保程序能准确执行。

怎么解决headersalreadysent的问题

为了使用页面跳转,我们只能提前发送header请求给浏览器。下面是一段例子代码,这段代码挂载到了admin_inithook上,在WordPress管理界面初始化后执行。代码主要的作用是判断当前页面和操作类型。如果操作类型满足一定条件,就执行一些数据处理和跳转操作。

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执行的时候,页面已经初始化了。再执行删除操作的时候,HTTPheader肯定已经发送了,如果在这个类中实现删除后跳转的操作,就会遇到headersalreadysent的警告。因此,我们需要跳出这个类,在页面初始化之前就来判断页面的操作以及是否需要跳转。

如果遇到类似的问题,在WordPress前台中也可以参考上面的代码来解决问题。只需要把admin_inithook换成前台页面初始化的hook即可。

添加UTHEME为好友
扫码添加UTHEME微信为好友
· 分享WordPress相关技术文章,主题上新与优惠动态早知道。
· 微信端最大WordPress社群,限时免费入群。