codeigniter 4 中设 http 状态码首选 $response->setstatuscode(),需在输出前调用;show_404()/show_error() 会自动设码并 exit;rest 场景用 $this->response() 统一处理;cli 下关注 exit 码而非 http 状态码。

直接用 $response->setStatusCode() 设置状态码
CodeIgniter 4 中控制器里改 HTTP 状态码最直接的方式,就是通过注入或获取的 Response 实例调用 setStatusCode()。它不依赖视图渲染,也不触发重定向,纯粹修改响应头里的 Status 行。
常见错误是试图在输出已发送后调用它(比如 echo 或 print_r 后再设),这时会抛出 Headers already sent 错误。
- 推荐在控制器逻辑早期、任何输出前调用,例如验证失败后立即设置
400或401 -
setStatusCode(404, 'Not Found')中第二个参数是可选的原因短语,浏览器不一定显示,但日志和调试工具会记录 - 若只传数字(如
setStatusCode(503)),框架会自动匹配内置原因短语('Service Unavailable') - 该方法不会自动终止执行,后续仍可调用
$this->response()或return $this->response(...)
show_404() 和 show_error() 的隐式状态码行为
这两个函数看似只是“显示错误页”,但它们内部会主动设置 HTTP 状态码并终止脚本 —— 这是容易被忽略的关键点。
比如你在控制器里写 show_404('user/123'),它不只是渲染 error_404.php,还会:
- 发送
HTTP/1.1 404 Not Found响应头 - 将 CLI 退出码设为
EXIT_UNKNOWN_FILE(定义在app/Config/Constants.php) - 立即
exit(),后面代码不再执行 -
show_error('DB failed', 500)会发500;但如果传99这种非法值,实际发出的是500(因小于 100)
REST 控制器中用 $this->response() 统一控制状态码与数据
如果你用的是 codeigniter-restserver 或 CI4 自带的 REST 支持,$this->response() 是更自然的选择。它把状态码、数据、Content-Type 封装在一起,避免手动设头遗漏。
示例:$this->response(['message' => 'Invalid token'], 401); 会自动:
- 设置
Content-Type: application/json - 调用
json_encode()并输出 - 调用
setStatusCode(401) - 终止当前请求流程(等效于
return) - 注意:如果传入的数组含中文或特殊字符,确保 PHP 的
json_encode()编码正常(建议统一 UTF-8)
别漏掉 CLI 场景下的退出码映射
在命令行运行控制器(比如定时任务)时,HTTP 状态码本身不生效,但 show_404()、show_error() 等函数仍会设置 PHP 的 exit() 码。这个码会被 shell 捕获用于判断任务成败。
比如 show_error('Config missing', 20) 在 CLI 下实际调用的是 exit(20 + EXIT__AUTO_MIN)(EXIT__AUTO_MIN 默认是 100),最终退出码是 120。运维脚本靠这个码做条件判断,所以别随意传非标准值。
真正容易踩的坑是:以为改了 HTTP 状态码就万事大吉,却没意识到 CLI 环境下它根本不走 HTTP 协议 —— 此时看的是 exit() 码,不是响应头。











