fastroute 路由必须用 addroute() 显式注册,不支持直接传配置数组;http 方法须大写,路径变量用 {id:d+} 语法;dispatch() 仅返回匹配结果,需手动 switch 处理三种状态并调用 handler。

FastRoute 路由注册必须用 addRoute(),不能直接传数组
很多人从 Laravel 或 Symfony 切过来,习惯写个路由配置数组然后丢给框架,但 FastRoute 不吃这套。它要求你显式调用 addRoute() 逐条注册,或用 addRoutes() 批量加——但批量传的也得是 addRoute() 那种结构,不是自由格式数组。
常见错误现象:TypeError: Argument 1 passed to FastRoute\Dispatcher\GroupCountBased::__construct() must be of the type array, null given,基本就是路由没注册上,simpleDispatcher() 拿到空数据了。
- 必须用
FastRoutesimpleDispatcher()包裹注册逻辑,里面调addRoute() - HTTP 方法要写全大写字符串:
'GET'、'POST',小写或混合大小写会匹配失败 - 路径中带变量用
{id:d+}这种语法,不支持 Laravel 风格的{id?}可选语法 - PHP 8.5 下注意闭包类型推导:如果用匿名函数当 handler,别漏写返回类型(如
function (): void),否则 strict mode 下可能报错
路由分发前必须先 dispatch(),且要处理三种返回类型
FastRoute 的 dispatch() 不是“执行”,只是“匹配 + 返回结果码”,真正的 handler 调用得你自己写 switch 块。很多人卡在这一步,以为 dispatch 后就自动跑了回调。
使用场景:你拿到 [$routeInfo[0], $routeInfo[1], $routeInfo[2]],其中 $routeInfo[0] 是状态码,只有三种:FastRouteDispatcher::NOT_FOUND、FastRouteDispatcher::METHOD_NOT_ALLOWED、FastRouteDispatcher::FOUND。
立即学习“PHP免费学习笔记(深入)”;
-
NOT_FOUND:路径完全没匹配,返回 404 -
METHOD_NOT_ALLOWED:路径对但方法错,比如用 POST 访问只注册了 GET 的路由,$routeInfo[1]里是允许的方法数组,可用来构造Allowheader -
FOUND:这时$routeInfo[2]是绑定的参数数组(如['id' => '123']),handler 才该被调用
示例片段:
switch ($routeInfo[0]) {
case FastRouteDispatcher::NOT_FOUND:
http_response_code(404); echo '404 Not Found'; break;
case FastRouteDispatcher::METHOD_NOT_ALLOWED:
http_response_code(405); header('Allow: ' . implode(', ', $routeInfo[1])); break;
case FastRouteDispatcher::FOUND:
$handler = $routeInfo[1];
$vars = $routeInfo[2];
$handler($vars); // 这里才真执行
break;
}
PHP 8.5 下 ReturnTypeWillChange 报错?关掉严格模式或补接口
FastRoute 本身没声明返回类型,但 PHP 8.5 默认启用 ReturnTypeWillChange 提示(非 fatal error,但开了 E_STRICT 或某些 IDE 就会标红)。这不是你的代码错,是 FastRoute 的 RouteCollector 类方法没加返回类型注解。
性能影响几乎为零,但开发体验差。兼容性上,PHP 8.5 + FastRoute 3.x 是能跑的,只是会看到警告。
- 临时方案:在
simpleDispatcher()调用前加error_reporting(E_ALL ^ E_STRICT)(仅开发环境) - 正经方案:自己写个 wrapper 类,实现
FastRouteRouteCollector接口,并补全所有方法的返回类型(如addRoute(): void) - 别试图改 vendor 里的 FastRoute 源码——下次
composer update就没了
RESTful 资源路由得手写,没有 resource() 一键生成
FastRoute 没内置资源路由(类似 Rails 的 resources :users),所有 CRUD 路径都得手动列清楚。想偷懒写个循环生成?可以,但要注意动词和路径语义别拧巴。
容易踩的坑:把 PUT /users/{id} 和 PATCH /users/{id} 当成一回事;或者用 GET /users/create 这种非标准路径假装有表单页——FastRoute 不管语义,但 RESTful 接口规范会咬你。
- 标准 REST 组合建议:
GET /users(列表)、POST /users(创建)、GET /users/{id}(详情)、PUT /users/{id}(全量更新)、PATCH /users/{id}(部分更新)、DELETE /users/{id} - PHP 8.5 下路径变量名别用下划线,比如
{user_id}—— FastRoute 解析器会把它当字面量,不是变量 - 如果项目真需要资源路由抽象,建议封装一个
addResource()工具函数,而不是硬塞进主 dispatch 流程
复杂点在于:路由逻辑和业务 handler 完全解耦,你得自己保证 $handler 函数能正确接收 $vars 并处理 HTTP 状态、JSON 输出、异常捕获——FastRoute 只管“找到谁来干”,不管“怎么干”。











