要在 workerman 4.0.10 中实现自动路由功能,必须显式使用 http:// 协议监听、解析 $request 路径、标准化 url、构建匹配路由表并优先处理静态资源,否则无法区分不同接口路径。

要在 Workerman 4.0.10 中实现自动路由功能,必须绕过框架原生缺失的路由层,手动解析请求路径并映射到对应处理逻辑——这一步不做,所有 URL 都会进入同一个 onMessage 回调,无法区分 /api/user 和 /static/logo.png。
启用 HTTP 协议并获取原始请求路径
Workerman 默认监听 TCP,不解析 HTTP 结构。必须显式声明 http:// 协议才能获得 $request 对象。
在 start.php 中定义 Worker 实例时,监听地址写成 http://0.0.0.0:8080,不能是 tcp:// 或只写端口。
确保已引入 Workerman\Protocols\Http\Request 类,但无需 new 实例——框架会在 onMessage 回调中自动注入 $request 参数。
若跳过此步,$_SERVER['REQUEST_URI'] 将为空或不可靠,后续所有路由匹配都失效。
手动解析 URL 路径并提取关键段
使用 PHP 内置函数 parse_url() 提取路径部分,避免直接操作 $_SERVER['REQUEST_URI'] ——它可能含查询参数、锚点,干扰路由判断。
方法一:基础路径截取
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
方法二:去除重复斜杠并标准化(防 /api//user/123 匹配失败)
$path = rtrim(str_replace('//', '/', parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)), '/');
注意:不要用 basename() 或 explode('/', $uri)[1] 这类脆弱方式——遇到根路径 / 或带版本前缀 /v1/api/user 会直接崩。
构建路由表并匹配处理函数
第一步:定义路由规则数组,键为正则或字符串路径,值为回调函数或控制器方法。
第二步:遍历路由表,用 preg_match 或 === 判断是否命中。
第三步:命中后立即 return,防止后续规则误触发。
示例代码片段:
$routes = [
'#^/api/users/(\d+)$#' => function ($id) use ($connection) {
return $connection->send("User ID: {$id}");
},
'/health' => fn() => $connection->send('OK'),
];
foreach ($routes as $pattern => $handler) {
if (is_string($pattern) && $path === $pattern) {
$handler();
return;
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
} elseif (is_string($pattern) && preg_match($pattern, $path, $matches)) {
array_shift($matches); // 去掉完整匹配项
$handler(...$matches);
return;
}
}
$connection->send("HTTP/1.1 404 Not Found\r\nContent-Type: text/plain; charset=utf-8\r\n\r\n404");
静态资源快速响应(/static/ 开头路径)
检测路径是否以 /static/ 开头,若是,则拼接真实文件路径,读取并返回内容。
if (str_starts_with($path, '/static/')) {
$file = __DIR__ . '/public' . $path;
if (is_file($file) && is_readable($file)) {
$ext = pathinfo($file, PATHINFO_EXTENSION);
$mime = match($ext) {
'js' => 'application/javascript',
'css' => 'text/css',
'png' => 'image/png',
'jpg' => 'image/jpeg',
default => 'text/plain',
};
$connection->header('Content-Type', $mime);
$connection->send(file_get_contents($file));
return;
}
}
这一步必须放在路由匹配之前执行,否则 /static/logo.png 会被当成动态接口处理,导致 404。










