直接运行 composer require nikic/fast-route 即可安装,注意命名格式、php版本要求(v2.x需≥8.0)、避免与现有框架路由冲突,并正确处理psr-7路径截取、注册顺序及匹配逻辑。

怎么用 Composer 安装 nikic/fast-route
直接运行 composer require nikic/fast-route 就行,不需要额外配置仓库或改源(它在 Packagist 默认索引里)。注意别手误写成 fast-route(少 nikic/)——会报 Could not find package fast-route。
常见错误是项目里已有旧版 psr/http-message 或 psr/http-server-handler,导致依赖冲突。如果看到类似 Conclusion: don't install nikic/fast-route v1.3.0 的提示,说明版本不兼容,优先升级 composer update psr/http-message psr/http-server-handler 再重试。
实操建议:
- 安装前确认 PHP 版本 ≥ 7.4(
v2.x要求 ≥ 8.0) - 不推荐用
--dev安装——路由是运行时依赖,不是开发工具 - 如果项目已用 Laravel 或 Slim,别硬塞
fast-route,它们自带路由,强行替换反而破坏中间件链
为什么不用 symfony/routing 做轻量路由
symfony/routing 功能全,但默认带 YAML 解析、表达式语言、缓存生成器等——哪怕你只定义 3 条 GET 路由,也会加载一堆没用的类。启动耗时多 3–5ms,内存多占 1MB+,对 CLI 脚本或 Serverless 场景明显拖累。
而 nikic/fast-route 是纯 PHP 数组编译 + 正则匹配,无反射、无配置文件解析,Dispatcher 实例化后就是个函数调用,适合真正轻量的场景(比如 API 网关、静态资源代理、CLI HTTP 服务)。
实操建议:
- 只用
FastRoute\simpleDispatcher(),别碰cachedDispatcher()——缓存需写文件,本地开发容易权限报错,上线又得配 opcache - 避免在路由闭包里写业务逻辑,用
[$handler, $method]返回数组,把执行交给统一 handler - 路径参数必须显式声明,
/user/{id:\d+}比/user/{id}更安全,否则可能匹配到/user/new导致 404 隐患
fast-route 怎么跟 PSR-7 请求对象配合
fast-route 本身不绑定任何 HTTP 抽象层,它只返回匹配结果($routeInfo 数组),你要自己桥接 PSR-7。常见坑是直接传 $request->getUri()->getPath() 给 dispatch(),却忘了去掉 base path(比如部署在 /api/v1 下)。
正确做法是先用 $request->getUri()->getPath() 取路径,再用 ltrim($path, $basePath) 截掉前缀,再传给 dispatcher。否则所有路由都 404。
实操建议:
- 别用
$_SERVER['PATH_INFO']—— CGI/FastCGI 环境下它不可靠,尤其 Nginx + PHP-FPM - 用
guzzlehttp/psr7或nyholm/psr7构造请求对象,别自己实现ServerRequestInterface - 匹配失败时,
$routeInfo[0] === FastRoute\Dispatcher::NOT_FOUND,不是null或空数组
为什么路由注册顺序会影响匹配结果
fast-route 不是“最长前缀匹配”,而是按注册顺序逐条比对正则。比如先注册 GET /user/{id},再注册 GET /user/profile,那 /user/profile 永远不会被命中——因为 {id} 的正则 /.+/ 先匹配成功了。
这和 Laravel/Symfony 的“精确路径优先”不同,是设计使然:牺牲一点便利性,换来更可预测的匹配行为(尤其是动态参数多时)。
实操建议:
- 把静态路径(如
/health、/favicon.ico)放在最前面 - 把带复杂正则的路由(如
/post/{slug:[a-z0-9\-]+})放静态路径之后、泛匹配之前 - 绝对不要写
GET /{any:.+}这种兜底路由——它会让所有 404 请求都进业务层,掩盖真实问题
真正难的不是装上插件,是搞清哪条路由该在哪儿注册、路径截取要不要 trim、匹配失败后怎么统一处理 404。这些细节不写进日志,线上就只能靠 curl 猜。










