workerman的_onmessage收不到post数据是因为默认使用tcp协议而非http,需改用workerman\protocols\http启动http服务器;若用http,则通过$request->post()或$request->rawbody()获取数据,原生$_post始终为空。

Workerman里_onMessage收不到POST数据?先确认协议类型
Workerman默认用的是纯TCP,不是HTTP——所以_onMessage收到的只是原始字节流,压根没有“POST”“GET”概念。你看到的$_POST为空、file_get_contents('php://input')为空、甚至整个请求体像乱码,大概率是因为没走HTTP协议栈。
实操建议:
- 如果想用
$_POST、$_GET、$_FILES这些PHP超全局变量,必须用Workerman\Protocols\Http,启动HTTP服务器,而不是裸TCP - 如果坚持用TCP(比如做自定义协议或长连接推送),就得自己解析HTTP报文——但别手写,容易漏掉分块传输、编码、边界处理等坑
- 检查你的客户端是不是真发了HTTP请求:用
curl -X POST -d "a=1" http://127.0.0.1:2346测试,而不是直接telnet连端口发字符串
用HTTP协议时_onMessage怎么拿到POST内容
Workerman的HTTP Server在_onMessage回调里传入的是Workerman\Protocols\Http\Request对象,不是原生$_POST。它封装了解析逻辑,但需要主动调用方法取值。
常见错误现象:直接打印$request->post()返回空数组,其实是因为没设置正确的Content-Type,或者POST体是JSON没走表单解析流程。
实操建议:
-
$request->post()只解析application/x-www-form-urlencoded和multipart/form-data,对application/json无效 - JSON请求要用
$request->rawBody()拿原始body,再json_decode($request->rawBody(), true) - 注意
$request->post()不支持嵌套字段(如a[b][c]=1),PHP原生也有限制,别指望它能还原复杂结构 - 上传文件需确保
Content-Type: multipart/form-data且带正确boundary,$request->file()才可用
$_POST为什么始终为空?检查SAPI和运行模式
Workerman不是PHP-FPM,也不走Apache/Nginx那套SAPI机制。$_POST是PHP在Web SAPI下自动填充的,Workerman的HTTP Server绕过了这个过程,所以原生$_POST永远为空——这不是bug,是设计如此。
性能影响:依赖$_POST会触发PHP内部的php_default_post_reader,但在Workerman里这个钩子根本没注册,强行include或模拟反而增加开销、破坏请求上下文。
实操建议:
- 彻底放弃
$_POST,统一用$request->post()或$request->rawBody() - 不要在
_onMessage里require其他框架入口(比如ThinkPHP的index.php),它们强依赖$_POST,大概率崩 - 调试时用
var_export($request->header())和var_export($request->rawBody())看真实输入,比猜靠谱
POST数据过大或中文乱码怎么办
Workerman默认不限制body大小,但PHP配置和Workerman自身缓冲区会影响实际接收。中文乱码通常不是编码问题,而是没正确声明Content-Type: application/x-www-form-urlencoded; charset=utf-8,导致$request->post()用ISO-8859-1解码。
实操建议:
- 限制body大小:在
Worker构造后加$worker->count = 128;控制并发,再用$request->maxRequestSize(10 * 1024 * 1024)设单次最大10MB - 中文正常显示:确保客户端Header里有
Content-Type且含charset=utf-8;服务端不用转码,$request->post()已按声明编码解析 - 如果客户端无法改Header(比如某些IoT设备),可在
_onMessage里手动mb_convert_encoding($request->rawBody(), 'UTF-8', 'GBK'),但得先判断来源
Workerman处理POST的本质是「协议决定能力」——用HTTP就老实用Request对象,用TCP就自己定规矩。最容易被忽略的是:很多人在TCP Worker里硬塞HTTP解析逻辑,结果遇到分包、粘包、chunked编码就卡死,不如一开始就选对协议。










