onrequest回调必须且仅接收$request和$response两个参数,顺序不可颠倒;需通过$request->get/post/rawcontent()等方法获取数据,$response必须显式调用end()等方法才能响应。

onRequest 回调函数签名必须是两个参数
在 Swoole HTTP 服务器中,onRequest 回调函数**必须且只能接收两个参数**:第一个是 $request(Swoole\Http\Request 实例),第二个是 $response(Swoole\Http\Response 实例)。少一个、多一个、顺序颠倒都会导致请求无响应或直接报错(如 Fatal error: Uncaught TypeError)。
常见错误写法包括:
-
function onRequest($request) { ... }—— 缺少$response,后续无法返回数据 -
function onRequest($response, $request) { ... }—— 参数顺序反了,$request->get会报错或取不到值 -
function onRequest($request, $response, $server) { ... }—— 多余参数,Swoole 不传第三个参数,运行时不会报语法错但逻辑不可控
如何正确访问 GET/POST 数据和请求头
$request 对象不是超全局数组,所有数据都需通过属性或方法获取,且大小写敏感、路径不自动解析(比如不处理 PATH_INFO)。
实操要点:
-
$request->get获取 URL 查询参数(GET),等价于$_GET,但它是只读数组,不能修改 -
$request->post获取表单提交的 POST 数据(application/x-www-form-urlencoded或multipart/form-data中的非文件字段),不支持原始 JSON body -
$request->rawContent()用于读取原始请求体(如 JSON、XML),需手动json_decode -
$request->header是关联数组,键全部小写(如$request->header['user-agent']),不存在自动转驼峰 -
$request->cookie、$request->server同理,都是小写键名,且不含HTTP_前缀
response 必须显式 end() 才能发回客户端
$response 不像 PHP-FPM 那样自动输出,**不调用 end()、write() 或 redirect(),客户端就永远收不到响应**,浏览器会 pending 直到超时。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
关键规则:
-
$response->end('hello')发送字符串并关闭连接,最常用 -
$response->write('part1'); $response->write('part2'); $response->end();分块发送,适合流式场景 -
$response->status(404); $response->end('Not Found');状态码必须在end()前设置 - 不能在
end()后再调用任何$response方法,否则触发 warning 且无效 - 如果忘记
end(),进程不会崩溃,但该连接卡死,日志里也无明显报错,极难排查
注意协程环境下的变量生命周期
在启用协程(enable_coroutine => true)的 Swoole 服务器中,onRequest 运行在独立协程里,但 $request 和 $response 对象**不是跨协程共享的**,也不可被 yield 后继续使用。
容易踩的坑:
- 在
go(function () use ($request) { ... })里直接使用$request->get—— 协程切换后$request可能已被回收,读取结果为空或报错 - 把
$response存进全局变量或静态属性,试图在异步回调里调用end()—— 违反 Swoole 的响应模型,会失败 - 需要异步处理时,应先提取所需数据(如
$uid = $request->get['uid'] ?? null;),再传入协程,而不是传对象本身
复杂点在于:这些错误往往不立即报错,而是在高并发或特定调度下才暴露,调试时得盯住协程上下文和对象引用关系。










