应使用框架内置方法输出JSON:CI3用$this->output->set_content_type()->set_output(),CI4用$this->response->setJSON(),避免手动header+echo导致的Content-Type错误、BOM干扰和输出缓冲问题。

直接用 json_encode() 输出会丢 header
很多新手写 echo json_encode($data); 就完事,结果前端收到的是纯文本,Content-Type 还是 text/html。浏览器或 Axios 不会自动当 JSON 解析,response.data 可能是字符串而非对象。
必须手动设 header:
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data);
exit;
但这样每次都要写两行,还容易漏 exit 导致后续代码执行(比如又输出了视图)。
用 $this->output->set_content_type()->set_output() 更稳
CodeIgniter 3 内置的 Output 类专为这类响应设计,自动处理 header、编码、终止流程,比手写 header() + echo 更可靠。
推荐写法:
$this->output
->set_content_type('application/json')
->set_output(json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR));
-
JSON_UNESCAPED_UNICODE避免中文变\u4f60,接口更可读 -
JSON_PARTIAL_OUTPUT_ON_ERROR防止某些非标数据(如资源句柄)导致整个json_encode()返回false,至少能输出部分结构 - 不用
exit——set_output()会接管响应,后续视图不会被加载
CI4 里直接用 json() 方法最省事
CodeIgniter 4 把这个逻辑封装成了控制器基类方法:$this->response->setJSON($data) 或更简洁的 return $this->response->setJSON($data);
它自动:
- 设
Content-Type: application/json - 调用
json_encode()并处理常见错误(如循环引用会抛异常,但至少不静默失败) - 支持链式设置状态码:
$this->response->setStatusCode(201)->setJSON($data)
注意:CI4 中不能在控制器里用 echo 或 print 混合输出,必须统一走 $this->response 返回。
别忽略 UTF-8 BOM 和输出缓冲干扰
即使写了正确 header,如果控制器文件本身带 BOM(比如用 Windows 记事本保存过),或前面有空格/换行,PHP 会提前发送响应头,导致 header() 失败并报 Cannot modify header information 错误。
排查建议:
- 用 VS Code 或 Sublime 打开控制器文件,检查右下角编码是否为
UTF-8 without BOM - 确认文件开头**没有任何字符**(包括空格、
前的换行) - 如果用了自定义钩子(hooks)或第三方库,它们可能提前输出内容,加一句
ob_get_level() && ob_end_clean();在json输出前清空缓冲区
真正卡住人的往往不是语法,而是这些看不见的空白和编码残留。











