同事做API接口,参数不合法时想返回404,写了header(HTTP/1.1 404 Not Found)却发现页面还是200,前端判断逻辑全乱。php里用header发404状态码,有几个细节不注意就白写。

正确的两种写法

header(HTTP/1.1 404 Not Found);
http_response_code(404);

推荐用http_response_code,它不依赖协议版本,PHP 5.4以上都支持,也不受服务器是HTTP/1.0还是2.0影响。老写法必须带完整的状态行,只写数字或只写Not Found都不生效。

为什么设了还是200

  • 前面有输出:header必须在任何输出之前调用,哪怕一个空格或BOM头都会让设置失败并报headers already sent。
  • 被后续覆盖:框架或缓存层在你之后又发了200头。
  • 重定向干扰:先设了Location又设404,浏览器优先处理跳转。

404之外的配合

光发状态码不够,还要给响应体。API返回JSON时,body里也要写明错误信息,前端拿状态码做逻辑、拿body做提示。返回404时记得同时声明Content-Type,否则浏览器可能按HTML解析。RESTful里资源不存在用404,参数错误其实更适合400,别一律404。

排查headers already sent

报这个错说明有东西提前输出了。把报错行号看完,往文件开头找空行、BOM和调试输出。用ob_start在入口开启输出缓冲也能兜底,但根本办法还是保证header在任何echo之前。文件保存时选无BOM的UTF-8。