文档目录
路由系统

简介

本文件系统性梳理 DouPHP 框架的路由体系,覆盖前台、后台、API 三端路由的差异化实现,解释委托式路由器、解析器模式与匹配算法,说明 URL 到控制器的映射机制、参数绑定、中间件集成,并给出语言前缀处理、动态路由生成、RESTful 路由设计与性能调优策略。

项目结构

  • 前端入口路由薄壳:负责将请求交给前端解析器,统一处理未匹配时的页面提示。
  • 后端入口路由薄壳:负责将请求交给后端解析器,统一处理未匹配与方法不允许的重定向与提示。
  • API 入口路由薄壳:负责将请求交给 API 解析器,统一返回 JSON 错误响应。
  • 中央分发器:在中间件管道中实例化控制器并调用方法,不关心具体路由决策。
  • 分发计划:不可变值对象,承载最终控制器、方法、参数与中间件链。
  • 动作解析器:路径动作段到控制器方法的智能映射(兼容驼峰/蛇形/横线)。
  • 前端外观匹配器:基于声明式规则表进行正则匹配与消歧,支持短地址策略。
  • 语言前缀解析器:在前台入口剥离多语言前缀,交由后续流程使用。
  • 路由风格配置:集中定义多种 URL 风格与规则族,用于前端外观 URL 的展开与匹配。
graph TB
subgraph "前端"
FR["Front Router"]
FRes["Front Resolver"]
PM["PrettyRouteMatcher"]
LPP["LangPrefixParser"]
end
subgraph "后台"
AR["Admin Router"]
ARes["Admin Resolver"]
end
subgraph "API"
R["Api Router"]
Res["Api Resolver"]
end
D["Dispatcher"]
DP["DispatchPlan"]
MR["MethodResolver"]
LPP --> FR
FR --> FRes
FRes --> PM
FRes --> MR
FRes --> D
AR --> ARes
AR --> D
R --> Res
Res --> D
D --> DP

图示来源

  • front/foundation/routing/Router.php:26-58
  • front/foundation/routing/FrontResolver.php:32-106
  • front/foundation/routing/LangPrefixParser.php:21-58
  • front/foundation/routing/PrettyRouteMatcher.php:25-114
  • admin/foundation/routing/Router.php:26-66
  • admin/foundation/routing/AdminResolver.php:30-104
  • api/foundation/routing/Router.php:28-70
  • api/foundation/routing/ApiResolver.php:30-91
  • core/web/Routing/Dispatcher.php:25-61
  • core/web/Routing/DispatchPlan.php:21-113
  • core/web/Routing/MethodResolver.php:23-71

章节来源

  • front/foundation/routing/Router.php:26-58
  • admin/foundation/routing/Router.php:26-66
  • api/foundation/routing/Router.php:28-70

核心组件

  • 委托路由器(薄壳):各端 Router 仅做“解析 → 分发”编排,不实现匹配逻辑。
  • 解析器(Resolver):按端特性加载默认中间件栈、读取命中条目、组装 DispatchPlan。
  • 中央分发器(Dispatcher):统一执行中间件管道、懒实例化控制器、注入路由参数。
  • 分发计划(DispatchPlan):封装 fqcn/method/params/middlewares 及 404/405 状态。
  • 动作解析器(MethodResolver):路径动作段到控制器方法的智能映射。
  • 前端匹配器(PrettyRouteMatcher):基于声明式规则的正则匹配、消歧与短地址策略。
  • 语言前缀解析器(LangPrefixParser):剥离 zh-cn 等语言前缀,供前端流程使用。
  • 路由风格配置(route.php):集中管理多种 URL 风格与规则族,支撑外观 URL 生成与匹配。

章节来源

  • core/web/Routing/Dispatcher.php:25-61
  • core/web/Routing/DispatchPlan.php:21-113
  • core/web/Routing/MethodResolver.php:23-71
  • front/foundation/routing/PrettyRouteMatcher.php:25-114
  • front/foundation/routing/LangPrefixParser.php:21-58
  • config/route.php:15-356

架构总览

三端采用“委托路由器 + 解析器 + 中央分发器”的统一架构:

  • 前端:入口 Router → FrontResolver → PrettyRouteMatcher(声明式规则匹配)→ Dispatcher。
  • 后台:入口 Router → AdminResolver(声明式匹配)→ Dispatcher。
  • API:入口 Router → ApiResolver(声明式匹配)→ Dispatcher。
sequenceDiagram
participant C as "客户端"
participant FR as "前端Router"
participant FRes as "FrontResolver"
participant PM as "PrettyRouteMatcher"
participant D as "Dispatcher"
participant M as "中间件管道"
participant Ctrl as "控制器"
C->>FR : 请求(已剥语言前缀)
FR->>FRes : resolve()
FRes->>PM : normalize(route, method)
PM-->>FRes : {module, action, controller, params}
FRes->>D : run(plan)
D->>M : 执行中间件链
M->>Ctrl : 调用方法
Ctrl-->>D : Response/null
D-->>FR : 响应
FR-->>C : 输出

图示来源

  • front/foundation/routing/Router.php:26-58
  • front/foundation/routing/FrontResolver.php:32-106
  • front/foundation/routing/PrettyRouteMatcher.php:54-114
  • core/web/Routing/Dispatcher.php:25-61

详细组件分析

前端路由(前台)

  • 语言前缀处理:LangPrefixParser 在入口阶段剥离 zh-cn 等前缀,将语言标识与剩余路由分别写入 Request。
  • 匹配策略:FrontResolver 通过 PrettyRouteMatcher 对声明式规则进行正则匹配;空串首页短路到 IndexController。
  • 短地址策略:当启用短地址时,禁止带模块前缀的长格式;若未命中,尝试补回模块前缀再匹配一次,保证可逆。
  • 中间件装配:默认栈为安全头 → 可信代理 → 限流 → [会员认证] → CSRF;可通过命中条目的 mw_* 字段进行路由级细化。
  • 参数绑定:具名捕获组作为路由参数注入 Request,并在 Dispatcher 之前设置,确保中间件与控制器均可读取。
  • 表单目标装配:create/edit 动作自动装配 form_action/form_method,便于模板渲染。
flowchart TD
Start(["前端请求"]) --> Strip["LangPrefixParser 剥离语言前缀"]
Strip --> Match{"PrettyRouteMatcher 匹配"}
Match --> |命中| Build["构建结果<br/>module/action/controller/params"]
Match --> |未命中| NotFound["返回 notFound()"]
Build --> MW["组装中间件链"]
MW --> Dispatch["Dispatcher.run()"]
Dispatch --> End(["完成"])
NotFound --> End

图示来源

  • front/foundation/routing/LangPrefixParser.php:21-58
  • front/foundation/routing/PrettyRouteMatcher.php:54-114
  • front/foundation/routing/FrontResolver.php:52-106
  • core/web/Routing/Dispatcher.php:41-59

章节来源

  • front/foundation/routing/Router.php:26-58
  • front/foundation/routing/FrontResolver.php:32-106
  • front/foundation/routing/LangPrefixParser.php:21-58
  • front/foundation/routing/PrettyRouteMatcher.php:25-114

后台路由(管理端)

  • 入口形式:以 route=module[/id[/action]] 进入,由 AdminResolver 通过声明式匹配器决定控制器与方法。
  • 中间件栈:默认包含安全头、可信代理、认证、权限、CSRF、工作区;可按命中条目叠加或豁免。
  • 错误处理:未匹配重定向至后台首页并携带错误提示;方法不允许返回 405 并附带 Allow 头。
  • 参数绑定:路径参数经 Request 独立路由袋注入,不写超全局。
sequenceDiagram
participant U as "管理员"
participant AR as "Admin Router"
participant ARes as "Admin Resolver"
participant D as "Dispatcher"
U->>AR : GET /admin?route=...
AR->>ARes : resolve()
ARes-->>AR : DispatchPlan
AR->>D : run(plan)
D-->>AR : Response/null
AR-->>U : 跳转/响应

图示来源

  • admin/foundation/routing/Router.php:26-66
  • admin/foundation/routing/AdminResolver.php:30-104
  • core/web/Routing/Dispatcher.php:25-61

章节来源

  • admin/foundation/routing/Router.php:26-66
  • admin/foundation/routing/AdminResolver.php:30-104

API 路由(接口端)

  • 入口形式:同样以 route=module[/id[/action]] 进入,由 ApiResolver 进行声明式匹配。
  • 中间件栈:默认包含安全头、可信代理、限流;可选用户认证(根据功能开关)。
  • 错误处理:未匹配与方法不允许均返回 JSON 错误(404/405),便于客户端消费。
  • 参数绑定:路径参数注入 Request 路由袋,中间件与控制器均可访问。
sequenceDiagram
participant Client as "客户端"
participant R as "Api Router"
participant Res as "Api Resolver"
participant D as "Dispatcher"
Client->>R : POST /api?route=...
R->>Res : resolve()
Res-->>R : DispatchPlan
R->>D : run(plan)
D-->>R : Response/null
R-->>Client : JSON 响应

图示来源

  • api/foundation/routing/Router.php:28-70
  • api/foundation/routing/ApiResolver.php:30-91
  • core/web/Routing/Dispatcher.php:25-61

章节来源

  • api/foundation/routing/Router.php:28-70
  • api/foundation/routing/ApiResolver.php:30-91

中央分发器与分发计划

  • 分发器职责:接收 DispatchPlan,先注入路由参数,再执行中间件管道,最后懒实例化控制器并调用方法。
  • 分发计划:不可变值对象,封装 fqcn/method/params/middlewares,并提供 notFound()/methodNotAllowed() 工厂方法。
  • 方法解析:MethodResolver 将路径动作段转换为控制器方法名,兼容 snake_case/camelCase/横线转驼峰,并处理保留字别名。
classDiagram
class Dispatcher {
+run(plan, container) mixed
}
class DispatchPlan {
+fqcn
+method
+params
+middlewares
+isNotFound() bool
+isMethodNotAllowed() bool
+notFound() DispatchPlan
+methodNotAllowed(allow) DispatchPlan
}
class MethodResolver {
+resolve(pathAction, controllerClass) string
}
Dispatcher --> DispatchPlan : "消费"
Dispatcher --> MethodResolver : "使用"

图示来源

  • core/web/Routing/Dispatcher.php:25-61
  • core/web/Routing/DispatchPlan.php:21-113
  • core/web/Routing/MethodResolver.php:23-71

章节来源

  • core/web/Routing/Dispatcher.php:25-61
  • core/web/Routing/DispatchPlan.php:21-113
  • core/web/Routing/MethodResolver.php:23-157

前端匹配器与风格规则

  • 匹配算法:收集全部命中规则,按 specificity 排序(占位符少优先、字面段多优先、声明顺序兜底),再按 HTTP 方法进行过滤。
  • 短地址策略:启用后禁止模块前缀长格式;未命中时尝试补回模块前缀重试,保证短链与完整规则可逆。
  • 风格规则:config/route.php 集中定义 PAGE/COLUMN/SIMPLE 等多类风格与规则族,支持 {param}/{param:regex}、[/optional] 等语法,并可扩展 short_rules 家族。
flowchart TD
A["输入路径"] --> B["收集命中规则"]
B --> C{"有命中?"}
C --> |否| E["返回未匹配"]
C --> |是| D["specificity 排序"]
D --> F{"HTTP 方法匹配?"}
F --> |是| G["构建结果并返回"]
F --> |否| H{"短地址重试?"}
H --> |是| I["补回模块前缀再匹配"]
I --> J{"命中?"}
J --> |是| G
J --> |否| E
H --> |否| E

图示来源

  • front/foundation/routing/PrettyRouteMatcher.php:116-169
  • front/foundation/routing/PrettyRouteMatcher.php:191-242
  • config/route.php:15-356

章节来源

  • front/foundation/routing/PrettyRouteMatcher.php:25-114
  • front/foundation/routing/PrettyRouteMatcher.php:116-169
  • config/route.php:15-356

依赖关系分析

  • 前端:Router → FrontResolver → PrettyRouteMatcher → Dispatcher;LangPrefixParser 在入口阶段剥离语言前缀。
  • 后台:Router → AdminResolver → Dispatcher。
  • API:Router → ApiResolver → Dispatcher。
  • 公共:Dispatcher 依赖 DispatchPlan 与 MethodResolver;所有端共享中间件注册与管道机制。
graph LR
FrontRouter["Front Router"] --> FrontResolver
FrontResolver --> PrettyMatcher
FrontResolver --> Dispatcher
AdminRouter["Admin Router"] --> AdminResolver
AdminResolver --> Dispatcher
ApiRouter["Api Router"] --> ApiResolver
ApiResolver --> Dispatcher
Dispatcher --> DispatchPlan
Dispatcher --> MethodResolver

图示来源

  • front/foundation/routing/Router.php:26-58
  • front/foundation/routing/FrontResolver.php:32-106
  • admin/foundation/routing/Router.php:26-66
  • admin/foundation/routing/AdminResolver.php:30-104
  • api/foundation/routing/Router.php:28-70
  • api/foundation/routing/ApiResolver.php:30-91
  • core/web/Routing/Dispatcher.php:25-61
  • core/web/Routing/DispatchPlan.php:21-113
  • core/web/Routing/MethodResolver.php:23-71

章节来源

  • front/foundation/routing/Router.php:26-58
  • admin/foundation/routing/Router.php:26-66
  • api/foundation/routing/Router.php:28-70

性能与缓存优化

  • 规则预编译:前端匹配器在构造期加载并预编译正则,减少运行时开销。
  • 短地址策略:避免重复匹配与冗余段,提升常见短链命中率。
  • 中间件按需装配:通过 mw_without/mw_append/mw_params 精细控制,减少不必要中间件执行。
  • 方法感知消歧:按 HTTP 方法过滤规则,降低无效匹配成本。
  • 建议:
    • 合理拆分规则族,优先将高频规则置于前面,缩短匹配时间。
    • 谨慎使用复杂正则,尽量用具名参数与字面段提高可读性与性能。
    • 结合业务开关(如 features.user)动态调整默认中间件栈,避免无谓校验。

故障排查指南

  • 前端未匹配:检查 LangPrefixParser 是否正确剥离语言前缀;确认 PrettyRouteMatcher 是否命中;查看日志中的 unmatched 记录。
  • 后台未匹配/方法不允许:确认 admin/route/*.php 中 declared 条目是否存在;检查 HTTP 方法与路由白名单;留意 405 的 Allow 头。
  • API 未匹配/方法不允许:确认 api/route/*.php 中 declared 条目与方法限制;关注 JSON 错误码与 allow 字段。
  • 控制器方法解析失败:核对 MethodResolver 的候选顺序与保留字映射;确保方法名符合命名约定。

章节来源

  • front/foundation/routing/FrontResolver.php:52-106
  • admin/foundation/routing/Router.php:41-66
  • api/foundation/routing/Router.php:43-70
  • core/web/Routing/MethodResolver.php:23-71

结论

DouPHP 的路由系统通过“委托路由器 + 解析器 + 中央分发器”的统一架构,实现了前台、后台、API 三端的解耦与一致性。前端采用声明式外观 URL 匹配与短地址策略,后台与 API 采用声明式资源路由;中间件分层装配保障安全与可扩展性;方法解析器提供灵活的 URL 到方法映射。配合风格化规则配置与性能优化手段,可满足复杂业务场景下的路由需求。

附录:配置语法与RESTful设计

  • 风格规则语法:
    • pattern:支持 {param}、{param:regex}、[/optional] 等语法。
    • params:可为参数提供默认正则;pattern 内嵌正则优先。
    • target:目标文件名模板,默认 {module}.php。
    • module_fixed:固定模块名,适用于 URL 不含模块段的情况。
    • short_rules:短地址模块专用规则族(column 风格),顶级分类别名取代模块名段,详情段取顶级祖先别名。
  • RESTful 路由设计:
    • 资源型路由建议使用 group/get 等声明方式,结合 HTTP 方法限定(update PUT、destroy DELETE)以实现 RESTful 语义。
    • 利用 MethodResolver 的保留字映射与候选顺序,使 URL 更直观且兼容历史命名。
  • 动态路由生成:
    • 前端 UrlBuilder 与匹配器共用同一编译引擎,保证生成与解析双向可逆。
    • 短地址策略下,生成与解析均遵循“省略模块前缀”的规则,避免歧义。

章节来源

  • config/route.php:15-356
  • front/foundation/routing/PrettyRouteMatcher.php:25-114
  • core/web/Routing/MethodResolver.php:23-71
添加日期:2026-10-05