Webman 的 json() 仅执行 json_encode() 并设置 Content-Type,不处理 HTTP 状态码、不封装 code/msg/data 统一结构、不区分成功/失败语义,直接使用会导致前端解析失败、格式不一致、错误响应错乱。

Webman 默认的 response() 和 json() 不带统一结构,直接返回数组或字符串会导致前端解析失败、状态码错乱、错误格式不一致——必须自己封装一层,不能依赖框架默认行为。
为什么不能直接用 json() 返回业务数据
Webman 的 json() 只做 json_encode() 并设 Content-Type: application/json,不处理 HTTP 状态码、不包装 code/msg/data 结构,也不区分成功/失败语义。常见问题包括:
- 控制器里写
return json(['user' => $user]),前端收到 200 但结构和错误响应不兼容 - 抛异常时没走自定义处理器,返回 HTML 错误页,uniapp 的
fail回调拿不到code -
json()默认不加JSON_UNESCAPED_UNICODE,中文变\u4f60\u597d(其实它加了,但很多人误以为没加)
如何封装一个 Result 工具类统一输出
推荐在 app/result/Result.php 中定义静态方法,所有控制器只调它,不直调 json() 或 response():
- 成功响应:用
Result::Success($data),固定返回 HTTP 200 +['code' => 0, 'msg' => 'ok', 'data' => $data] - 业务错误:用
Result::ErrorCode(4001, '用户名已存在'),HTTP 码仍为 200(除非你真要语义化,如 401 就用withStatus(401)) - 系统异常:在全局异常处理器中统一转成
Result::ErrorCode(5000, $e->getMessage()),避免裸 throw - 不要在工具类里自动过滤
password字段——那是 Controller 层该做的预处理
示例实现片段:
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
namespace app\result;
use support\Response;
class Result
{
public static function Success($data = null): Response
{
return response()->json(['code' => 0, 'msg' => 'ok', 'data' => $data]);
}
public static function ErrorCode(int $code, string $msg = '', $data = null): Response
{
return response()->json(['code' => $code, 'msg' => $msg, 'data' => $data]);
}
}
中间件里改响应体容易踩的坑
如果想在中间件中统一加字段(如 timestamp)、统一封装、或重写错误响应,注意以下几点:
- 中间件顺序很重要:
Result封装必须在日志、CORS、鉴权等中间件之后执行,否则 header 可能被覆盖 - 不要在中间件里对已有
Response实例反复调withStatus()或withHeader(),多次调用会叠加,不是覆盖 - 若捕获到
RateLimitExceededException,必须用response()->json([...])->withStatus(429),不能只设状态码不写 body——浏览器收不到内容会当成网络中断 - 别在中间件里
echo或var_dump(),Webman 是常驻内存模型,输出会打到终端,且可能破坏响应流
Uniapp 调用时参数和错误必须对齐
Uniapp 默认发 application/json,但 Webman 的 $request->post() 不解析它,导致取不到参数:
- 读参必须用
$request->json(),而不是$request->post() - 表单验证失败时,Respect\Validation 抛异常,默认返回 HTML,必须在
try/catch中手动转Result::ErrorCode(400, $e->getMessages()) - 全局异常处理器里,
render()方法必须显式调response()->json(),不能只return ['code'=>500],否则 Content-Type 是text/html - 调试时发现 JSON 没换行?那是正常行为——
json()默认不带JSON_PRETTY_PRINT,生产环境禁用它,否则体积涨、性能跌
最易忽略的一点:所有分支——包括 try、catch、if else、中间件拦截——都必须走同一套 Result 输出,否则前端要写一堆条件判断来适配不同格式。










