最稳妥方式是先调用$this->output->set_content_type()再调用set_output();若跳过框架可用header()+echo+exit();json接口须设application/json类型,避免text/plain导致前端解析失败。

直接用 output->set_content_type() + output->set_output()
CodeIgniter 2/3 默认把响应当作 HTML 处理,echo 或 return 字符串不会自动设 Content-Type,浏览器可能乱码或尝试解析为 HTML。最稳妥的方式是显式设置类型再输出:
-
$this->output->set_content_type('text/plain');—— 必须在set_output()前调用,否则无效 -
$this->output->set_output("Hello world");—— 替换整个响应体,不拼接、不缓存后续输出 - 不要混用
echo和set_output(),后者会覆盖前者(除非你手动禁用 output 类的自动输出)
exit() + header() 是更轻量的替代方案
如果你不需要走 CI 的 Output 类流程(比如调试接口、临时脚本),跳过框架中间层反而更可控:
-
header('Content-Type: text/plain; charset=utf-8');—— 显式声明编码,避免中文变 -
echo "status=ok";—— 直接输出,CI 不再接管后续响应 -
exit();—— 必须加,否则 CI 后续仍可能输出模板、debug 信息甚至空白行 - 注意:此方式绕过钩子(hooks)、缓存、安全过滤等,仅适合内部工具或简单 API 端点
别踩 read_file() 的坑:它不是为 HTTP 响应设计的
有人看到 read_file('./assets/text.txt') 返回字符串,就直接 echo read_file(...),这会导致两个问题:
- 文件路径基于
index.php位置,不是控制器所在目录,容易报FALSE却没检查返回值 -
read_file()已被官方标记为废弃,PHP 原生file_get_contents()更可靠,但同样要配header()才算完整响应 - 若文件含 BOM 或末尾空行,
read_file()会原样吐出,触发“headers already sent”错误
JSON 接口误用 text/plain 的典型症状
写 AJAX 接口时,明明返回的是 JSON 字符串,却设成 text/plain,结果前端 response.json() 报错:
- 浏览器不会报错,但
fetch().then(r => r.json())会抛Unexpected token—— 因为 Content-Type 不匹配 - 正确做法是
$this->output->set_content_type('application/json');,再set_output(json_encode([...])) - 纯文本场景下,如果内容里有换行、制表符,记得用
str_replace(["\r\n", "\r", "\n"], '\n', $str)统一,避免某些客户端解析异常
set_output() 被调用,CI 就不会再合并任何其他 view 或 buffer 内容;而用 exit() 则彻底放弃框架生命周期。选哪条路,取决于你是否还需要日志、钩子、或统一的响应包装逻辑。











