Flight 框架需手动注册 json() 函数:设置 Content-Type、状态码,用 json_encode() 输出并校验错误;避免裸 echo,统一入口防遗漏。

Flight 框架里怎么用 json() 返回 API 数据
Flight 默认不带 JSON 响应封装,json() 不是框架原生方法,直接调用会报 Fatal error: Call to undefined method Flight::json()。得自己注册一个路由响应函数或重写 Flight::json() 的行为。
最轻量的做法是注册一个全局响应函数:
Flight::set('json', function($data, $status = 200) {Flight::response()->header('Content-Type', 'application/json; charset=utf-8'); http_response_code($status); echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); });
- 必须加
JSON_UNESCAPED_UNICODE,否则中文变u4f60u597d -
JSON_UNESCAPED_SLASHES避免/这种冗余转义 - 别漏掉
http_response_code(),否则默认 200 无法覆盖错误状态 - 不能在
json()里做exit或die,Flight 的执行流程依赖后续中间件
为什么不能直接 echo json_encode() 就完事
裸 echo 缺少关键响应头和状态码控制,前端 fetch/fetcher 可能拿不到正确 Content-Type,导致解析失败;后端日志、网关(如 Nginx、Cloudflare)也可能因缺失 Content-Type 误判为文本响应。
- 没设
Content-Type→ 浏览器可能当text/html解析,response.json()报错 - 没调
http_response_code(400)→ 即使返回{"error":"xxx"},状态码还是 200,前端难区分成功 / 失败 - 没处理空数组 / 对象的 JSON 编码边界 →
json_encode(null)返回null字符串,不是"null",但这是 PHP 行为,不是 Flight 问题
处理空值、资源、循环引用时怎么防崩
json_encode() 遇到资源(如 mysqli_result)、闭包、含循环引用的对象会直接返回 false,且不报错——只静默失败,API 返回空响应,极难排查。
立即学习 “PHP 免费学习笔记(深入)”;
- 输出前先用
is_array()或is_object()判断,再用json_last_error() === JSON_ERROR_NONE校验 - 对数据库结果,务必先
fetch_all(MYSQLI_ASSOC)转成数组,别传mysqli_result对象进去 - 含 DateTime 的对象,提前用
$dt->format('c')转字符串,别依赖JsonSerializable(Flight 默认不启用) - 开发期可在
json()函数末尾加if (json_last_error() !== JSON_ERROR_NONE) {throw new Exception('JSON encode failed:' . json_last_error_msg()); }
要不要用第三方库替代手写 json()
没必要。Flight 极简,引入 symfony/http-foundation 或 slim/slim 的 Response 类反而破坏轻量性,还增加 autoloader 开销。手写 5 行已覆盖 95% 场景。
唯一值得换的情况是:你已经在用 PSR-7(比如用 nyholm/psr7),且整个项目统一用 ResponseInterface,那可以封装成 PSR-7 兼容的响应工厂。否则纯属过度设计。
真正容易被忽略的是:所有 JSON 响应都该走同一入口函数,而不是每个路由里重复写 header + echo。一旦漏掉某个分支的状态码或编码选项,线上就出不可见故障。