Workerman 5.2.3不内置$_POST/$_FILES,需手动解析:application/x-www-form-urlencoded用parse_str();multipart/form-data需按boundary分割或分离上传。

Workerman 5.2.3 本身是基于 PHP 的异步 TCP/HTTP 服务器框架,不内置传统 PHP 的 $_POST、$_FILES 等超全局变量,因为它绕过了 PHP-FPM 和 Web 服务器(如 Nginx/Apache)的请求解析流程。要接收 POST 表单数据(application/x-www-form-urlencoded 或 multipart/form-data),需手动解析原始请求体。
确认请求内容类型(Content-Type)
浏览器提交表单时,Content-Type 决定解析方式:
-
application/x-www-form-urlencoded:普通表单(无文件上传),数据在请求体中以key1=value1&key2=value2格式编码 -
multipart/form-data:含文件上传的表单,结构复杂,需边界(boundary)解析
Workerman 的 $request->header('content-type') 可获取该值,用于分支处理。
解析 application/x-www-form-urlencoded 数据
对纯文本表单,可直接用 PHP 原生函数解析原始请求体:
// 在 HTTP worker 的 onMessage 回调中(例如使用 WebServer)
$request = $connection->request;
if ($request->method() === 'POST' &&
stripos($request->header('content-type'), 'application/x-www-form-urlencoded') === 0) {
parse_str($request->rawBody(), $postData);
// $postData 是关联数组,等效于 $_POST
$username = $postData['username'] ?? '';
$email = $postData['email'] ?? '';
}
解析 multipart/form-data(含文件上传)
Workerman 5.2.3 不原生支持 multipart 解析,需借助第三方库或手动处理。推荐使用轻量库 symfony/http-foundation 或 php-http/message,但更常用的是自行调用 PHP 的 $_FILES —— 这需要配合临时 CGI 模式(不推荐)或改用 WebServer + 临时写入 + move_uploaded_file 模拟。
更稳妥的做法(适用于简单场景):
- 将原始请求体保存为临时文件
- 调用
parse_str()仅适用于 urlencoded;对 multipart,必须按 boundary 分割并提取字段和文件流 - 生产环境建议:前端上传文件走独立接口(如用
file_get_contents('php://input')接收二进制流),表单字段仍走 urlencoded;或改用 Nginx + PHP-FPM 处理复杂表单,Workerman 专注 API/长连接
完整 HTTP Server 示例(处理普通 POST)
use Workerman\Worker;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function ($connection, $request) {
if ($request->method() === 'POST') {
$contentType = $request->header('content-type');
if (stripos($contentType, 'application/x-www-form-urlencoded') === 0) {
parse_str($request->rawBody(), $data);
$response = new Response(200, ['Content-Type' => 'application/json'],
json_encode(['status' => 'success', 'data' => $data], JSON_UNESCAPED_UNICODE));
} else {
$response = new Response(400, ['Content-Type' => 'text/plain'], 'Only x-www-form-urlencoded supported');
}
} else {
$response = new Response(200, ['Content-Type' => 'text/html'],
'<form method="POST"><input name="name"><button>Submit</button></form>');
}
$connection->send($response);
};
Worker::runAll();
不复杂但容易忽略:务必检查 Content-Type,避免把 multipart 当 urlencoded 解析导致乱码或失败;文件上传建议分离处理或交由标准 Web 服务器代理。

















