文档目录
数据流转机制

简介

本文件面向 DouPHP 框架的数据流转机制,聚焦 HTTP 请求从接收到响应的完整链路:入口引导、路由解析、中间件执行、控制器调用、服务处理、模型操作、视图渲染与 API 响应。文档同时说明参数验证与过滤、异常处理流程、错误信息传递与状态码管理,并给出前后端分离场景下的数据交互模式与 API 接口规范。为便于理解,文中提供多幅流程图与时序图,标注了与源码文件的对应关系。

项目结构

DouPHP 采用“三端入口 + 核心引导 + 模块化路由”的架构:

  • 三个入口分别负责前台(网站)、API(JSON 接口)和后台(管理端),统一通过 core/bootstrap.php 完成环境初始化、常量定义、自动加载、容器与 Request 单例注册等。
  • 每个入口将自身的路由调度器委派给 Route::setDelegate(...),随后进入 Init::boot 进行应用级初始化,再由 Dispatcher 在中间件管道中执行目标控制器。
  • 路由风格集中配置于 config/route.php,支持多种 URL 风格与短地址模块规则;各端 Router 薄壳仅做解析与分发,不耦合业务。
graph TB
A["HTTP 客户端"] --> B["前台入口 index.php"]
A --> C["API 入口 api/index.php"]
A --> D["后台入口 admin/index.php"]
B --> E["核心引导 core/bootstrap.php"]
C --> E
D --> E
E --> F["前台路由 Router<br/>front/foundation/routing/Router.php"]
E --> G["API 路由 Router<br/>api/foundation/routing/Router.php"]
E --> H["后台路由 Router<br/>admin/foundation/routing/Router.php"]
F --> I["Dispatcher + 中间件管道"]
G --> I
H --> I
I --> J["控制器/服务/模型"]
J --> K["视图或 JSON 响应"]

核心组件

  • 入口与引导
    • 根入口 index.php:设置前台路由委托、剥离语言前缀、启动 Init、分发路由、统一异常处理(JSON/HTML)。
    • API 入口 api/index.php:设置 API 路由委托、写入 route、启动 Init、分发路由、统一 JSON 异常处理。
    • 后台入口 admin/index.php:设置后台路由委托、写入 route、启动 Init、分发路由、统一异常处理(AJAX/HTML)。
    • 核心引导 core/bootstrap.php:定义路径常量、协议判断、安装检查、加载配置、注册自动加载与别名、初始化 DI 容器、提前绑定 DelegatingRouter 与 Request 单例、加载助手函数、注册事件与场景。
  • 路由与调度
    • 前台 Router:读取 Request,经 FrontResolver 生成 DispatchPlan,未匹配返回 page_wrong,匹配后交由 Dispatcher 执行。
    • API Router:读取 Request,经 ApiResolver 生成 DispatchPlan,未匹配返回 404/405 JSON,匹配后交由 Dispatcher 执行。
    • 后台 Router:读取 Request,经 AdminResolver 生成 DispatchPlan,未匹配重定向到首页并携带提示,匹配后交由 Dispatcher 执行。
  • 中间件
    • 前台 SecurityHeadersMiddleware:基类实现安全响应头注入。
    • API UserAuthMiddleware:基于 AbstractUserAuthMiddleware,从 Authorization 头提取 token,解析登录态,拒绝时返回 401/403 JSON。
    • 后台 AuthMiddleware:从 Session 恢复管理员登录态,未登录抛 HttpResponseException 跳转登录页。
  • 控制器基类
    • API BaseController:继承核心 Base,提供会员中心导航构建等 API 专属能力。
    • 后台 BaseController:继承核心 Base,封装 view()、layoutVars()、flash 归一化、删除结果响应分流、开关切换响应分流等。

架构总览

下图展示一个典型的前台页面请求从浏览器到模板渲染的完整时序,包括语言前缀解析、Init 引导、路由解析、中间件管道、控制器与服务调用、视图渲染与响应发送。

sequenceDiagram
participant U as "浏览器"
participant FE as "前台入口 index.php"
participant BS as "核心引导 bootstrap.php"
participant FR as "前台路由 Router"
participant MW as "中间件管道"
participant CT as "控制器/服务/模型"
participant V as "视图引擎"
participant R as "Response"
U->>FE : "GET /?route=...&lang=..."
FE->>BS : "require bootstrap"
BS-->>FE : "常量/容器/Request 就绪"
FE->>FR : "dispatch()"
FR->>FR : "FrontResolver.resolve(Request)"
FR->>MW : "Dispatcher.run(DispatchPlan)"
MW->>CT : "调用控制器方法"
CT->>CT : "服务处理/模型操作"
CT->>V : "渲染视图"
V-->>CT : "HTML 内容"
CT-->>R : "ViewResponse"
R-->>U : "HTTP 200 + HTML"

详细组件分析

前台请求处理流程(Web 页面)

  • 入口职责
    • 设置前台路由委托、剥离语言前缀并写入 Request、启动 Init、分发路由、捕获 HttpResponseException/RedirectException/DomainException,按 JSON/HTML 分支输出。
  • 路由与调度
    • 前台 Router 使用 FrontResolver 解析出 DispatchPlan;未匹配返回 page_wrong;匹配后交给 Dispatcher 执行中间件管道与控制器。
  • 中间件
    • 前台默认包含安全响应头中间件,用于注入安全相关响应头。
  • 控制器与视图
    • 控制器通过 view() 返回 ViewResponse,由模板引擎渲染 HTML。
flowchart TD
Start(["请求进入前台入口"]) --> Parse["剥离语言前缀并写入 Request"]
Parse --> Boot["Init::boot() 初始化"]
Boot --> Resolve["FrontResolver 解析路由"]
Resolve --> |未匹配| NotFound["返回 page_wrong 提示"]
Resolve --> |匹配| Pipe["Dispatcher 运行中间件管道"]
Pipe --> Controller["调用控制器方法"]
Controller --> Service["服务处理/模型操作"]
Service --> Render["视图渲染"]
Render --> Send["发送 Response"]
NotFound --> End(["结束"])
Send --> End

API 请求处理流程(JSON 接口)

  • 入口职责
    • 设置 API 路由委托、写入 route、启动 Init、分发路由、捕获 DomainException 转为 422 JSON,其他异常统一走 api_render_uncaught 输出 JSON。
  • 路由与调度
    • API Router 使用 ApiResolver 解析出 DispatchPlan;未匹配返回 404/405 JSON;匹配后交由 Dispatcher 执行中间件管道与控制器。
  • 中间件
    • UserAuthMiddleware 从 Authorization 头提取 token,解析登录态;未认证返回 401,无工作身份返回 403。
  • 控制器与响应
    • 控制器通常返回 ApiResponse 或 JsonResponse;失败时抛出 DomainException 以统一 422 响应。
sequenceDiagram
participant C as "客户端"
participant API as "API 入口"
participant AR as "API 路由 Router"
participant MW as "中间件管道"
participant CTRL as "API 控制器"
participant S as "服务/模型"
participant RESP as "ApiResponse"
C->>API : "POST/GET /api/index.php?route=... (含 Authorization)"
API->>AR : "dispatch()"
AR->>MW : "运行中间件鉴权等"
MW->>CTRL : "调用控制器方法"
CTRL->>S : "执行业务逻辑"
S-->>CTRL : "返回数据/异常"
CTRL->>RESP : "success/error/422"
RESP-->>C : "JSON 响应"

后台请求处理流程(管理端)

  • 入口职责
    • 设置后台路由委托、写入 route、启动 Init、分发路由、捕获 DomainException 根据 AJAX 分支返回 JSON 或消息页。
  • 路由与调度
    • 后台 Router 使用 AdminResolver 解析出 DispatchPlan;未匹配重定向到首页并携带错误提示;匹配后交由 Dispatcher 执行中间件管道与控制器。
  • 中间件
    • AuthMiddleware 从 Session 恢复管理员登录态;未登录抛 HttpResponseException 跳转登录页。
  • 控制器与视图
    • 控制器通过 view() 返回 ViewResponse;支持 flash 消息、AI 工具栏注入、删除结果分流、开关切换响应分流等。
sequenceDiagram
participant A as "管理员浏览器"
participant ADM as "后台入口"
participant ARM as "后台路由 Router"
participant MW as "中间件管道"
participant CTRL as "后台控制器"
participant VIEW as "视图引擎"
participant RESP as "Response"
A->>ADM : "GET /admin/index.php?route=..."
ADM->>ARM : "dispatch()"
ARM->>MW : "运行中间件认证等"
MW->>CTRL : "调用控制器方法"
CTRL->>VIEW : "渲染模板"
VIEW-->>CTRL : "HTML"
CTRL-->>RESP : "ViewResponse"
RESP-->>A : "HTTP 200 + HTML"

路由风格与参数解析

  • 路由风格集中配置于 config/route.php,支持 PAGE、COLUMN、SIMPLE 三类风格,每种风格下有多条规则,涵盖分类别名、ID 后缀、日期归档、短地址模块等。
  • 规则中的命名参数会原样进入 params,由统一路由层解释;短地址模块可替换模块名段或使用特殊规则族。
  • 各端 Router 薄壳只读 Request,不直接访问超全局;路由字符串由入口写入 Request 后再被解析。
flowchart TD
RStart["接收 route 字符串"] --> Style["选择路由风格<br/>PAGE/COLUMN/SIMPLE"]
Style --> Match{"匹配规则"}
Match --> |是| Params["提取命名参数<br/>module/category_slug/id/slug/year/month"]
Match --> |否| NotFound["未匹配 -> 404/重定向"]
Params --> Plan["生成 DispatchPlan"]
Plan --> Next["进入中间件管道"]

中间件与鉴权

  • 前台安全头:通过基类注入安全相关响应头,提升安全性。
  • API 用户认证:从 Authorization 头提取 token,解析登录态;未认证返回 401,无工作身份返回 403。
  • 后台管理员认证:从 Session 恢复登录态;未登录抛异常跳转登录页。
classDiagram
class AbstractUserAuthMiddleware {
+handle(next) mixed
#resolveContext() array
#inject(context) void
#hasWorkIdentity() bool
#rejectUnauthenticated() void
#rejectForbidden() void
}
class UserAuthMiddleware {
+handle(next) mixed
#configFile() string
#resolveContext() array
#inject(context) void
#hasWorkIdentity() bool
#rejectUnauthenticated() void
#rejectForbidden() void
}
class AuthMiddleware {
+handle(next) mixed
}
AbstractUserAuthMiddleware <|-- UserAuthMiddleware

控制器与响应分流

  • API 控制器基类:提供会员中心导航构建等 API 专属能力;服务调用通过 helper/门面进行。
  • 后台控制器基类:封装 view()、layoutVars()、flash 归一化、删除结果分流、开关切换响应分流等;支持 AJAX 与 HTML 双通道响应。
flowchart TD
Ctrl["控制器方法"] --> Decide{"是否 AJAX/JSON?"}
Decide --> |是| JsonResp["返回 ApiResponse/JsonResponse"]
Decide --> |否| Flash["redirect()->with('success', msg)"]
JsonResp --> End(["结束"])
Flash --> End

依赖关系分析

  • 入口与引导
    • 三个入口均依赖 core/bootstrap.php 完成环境初始化与容器绑定。
  • 路由与调度
    • 各端 Router 依赖各自 Resolver 与中央 Dispatcher;未匹配时分别返回不同响应策略。
  • 中间件
    • API 鉴权依赖抽象基类与 auth('api') guard;后台鉴权依赖 session 与 redirect。
  • 控制器
    • API/后台控制器基类扩展核心 Base,提供场景化响应与视图能力。
graph LR
Bootstrap["core/bootstrap.php"] --> FE["前台入口 index.php"]
Bootstrap --> API["API 入口 api/index.php"]
Bootstrap --> ADM["后台入口 admin/index.php"]
FE --> FR["前台 Router"]
API --> AR["API Router"]
ADM --> ARM["后台 Router"]
FR --> Disp["Dispatcher"]
AR --> Disp
ARM --> Disp
Disp --> MW["中间件"]
MW --> CTRL["控制器"]
CTRL --> RESP["响应"]

性能考量

  • 入口与引导阶段尽量轻量:bootstrap.php 仅做必要初始化与绑定,避免阻塞请求。
  • 路由解析集中且可配置:通过 config/route.php 统一管理规则,减少硬编码与重复计算。
  • 中间件管道按需启用:仅在必要时开启鉴权与安全头注入,降低开销。
  • 视图渲染延迟:后台控制器 layoutVars() 与 AI 工具栏注入仅在真正渲染时执行,避免不必要的计算。
  • 缓存与存储:结合 Storage 与数据库连接配置,合理设置缓存策略以减少 IO 压力。

故障排查指南

  • 未捕获异常处理
    • 前台:记录日志,site.debug 开启时输出调试页或 JSON 500;否则回退到 page_wrong 提示或 JSON 500。
    • API:记录日志,site.debug 开启时输出 API 500;否则返回标准 JSON 500。
    • 后台:记录日志,AJAX/JSON 请求返回 {ok:false, error};site.debug 开启时输出调试页;否则回退到 page_wrong。
  • 常见错误定位
    • 检查入口是否正确设置路由委托与写入 route。
    • 检查中间件是否过早终止(如鉴权失败返回 401/403)。
    • 检查路由规则是否匹配,未匹配时查看 404/405 响应。
    • 检查控制器是否返回正确的 Response 类型(ViewResponse/ApiResponse/JsonResponse)。

结论

DouPHP 的数据流转机制以“入口引导 + 路由解析 + 中间件管道 + 控制器/服务/模型 + 响应”为核心,前台、API、后台三端共享核心引导与调度能力,同时在边界处差异化处理鉴权、异常与响应格式。通过集中化的路由风格配置与统一的异常处理策略,系统在保证灵活性的同时具备良好的可维护性与一致性。前后端分离场景下,API 端以 JSON 为主,配合鉴权中间件与标准错误码,确保接口稳定可靠。

附录

  • API 接口数据格式规范(建议)
    • 成功响应:{code: "SUCCESS", message: "...", data: {...}}
    • 业务规则违反:{code: "BUSINESS_RULE_VIOLATION", message: "...", errors: [...]}
    • 未认证:{code: "UNAUTHORIZED", message: "..."}
    • 禁止访问:{code: "FORBIDDEN", message: "..."}
    • 服务器错误:{code: "SERVER_ERROR", message: "..."}
  • 前后端数据交互模式
    • 前端通过 Accept 头协商 JSON;后端根据 wantsJson() 决定响应格式。
    • 表单提交与 AJAX 混合场景:后台控制器通过 respondToggle/respondDeleteResult 统一分流。
    • 路由参数通过 Request 独立路由袋注入,避免污染超全局。
添加日期:2026-10-05