文档目录
整体架构模式

简介

本文件面向 DouPHP 框架的整体架构模式,聚焦以下目标:

  • 高层设计决策:MVC 分层、模块化与插件化扩展机制。
  • 三端统一与差异:前台、后台、API 的入口、引导程序、路由与响应策略。
  • 请求处理流程与数据流向:从 HTTP 边界到控制器、服务、模型与视图/JSON 输出。
  • 系统边界、技术栈与依赖管理:容器、门面、配置、路由与中间件。
  • 可扩展性与性能:模块开关、主题与语言包、缓存与编译、错误处理与调试。
  • 引导程序与核心服务初始化:各端 Init::boot 的职责与顺序。

项目结构

DouPHP 采用“多入口 + 共享内核”的结构:

  • 根入口 index.php 负责前台应用;admin/index.php 负责后台;api/index.php 负责 API。
  • 所有入口先加载 core/bootstrap.php,完成环境检测、常量定义、自动加载、容器与全局助手注册。
  • 每个应用拥有独立的 Init(引导)、Routing(路由解析与调度)、Middleware(中间件)、Controller/Service/Model、View/Template。
  • 公共能力集中在 core/ 下:容器、配置、路由、HTTP、ORM、模板引擎、事件、扩展等。
graph TB
subgraph "入口层"
FE["前台入口<br/>index.php"]
AD["后台入口<br/>admin/index.php"]
AP["API入口<br/>api/index.php"]
end
subgraph "共享内核"
BS["核心引导<br/>core/bootstrap.php"]
CFG["站点配置<br/>config/config.php"]
CTN["容器/门面/助手"]
end
subgraph "应用层"
F_INIT["前台引导<br/>front/init/Init.php"]
A_INIT["后台引导<br/>admin/init/Init.php"]
I_INIT["API引导<br/>api/init/Init.php"]
F_RT["前台路由<br/>front/foundation/routing/Router.php"]
A_RT["后台路由<br/>admin/foundation/routing/Router.php"]
I_RT["API路由<br/>api/foundation/routing/Router.php"]
end
FE --> BS
AD --> BS
AP --> BS
BS --> CTN
FE --> F_INIT --> F_RT
AD --> A_INIT --> A_RT
AP --> I_INIT --> I_RT

核心组件

  • 引导程序 Init:封装各端启动流程,按序完成会话、时区、错误报告、根 URL、语言、核心对象实例化、Provider 注册、模块与语言包加载、视图引擎装配、通用变量注入、站点关闭检查等。
  • 路由 Router:每端一个薄壳 Router,读取 Request,调用 Resolver 生成 DispatchPlan,交由中央 Dispatcher 执行;未匹配时按端策略返回 404/重定向或 JSON。
  • 响应 Response:统一的 HTTP 响应抽象,支持状态码、头部与内容;API 使用 ApiResponse,Web 使用 view/redirect/response 助手。
  • 容器与门面:Container 提供单例与服务定位;Facade 提供 DB、Session、Route、Request、Url、Message、View 等便捷访问。
  • 配置与模块:Config 集中管理站点、系统、特性开关;Module 按需加载业务模块;features.* 控制功能启用。
  • 模板与视图:DouView 作为模板引擎,前后端分别装配不同模板目录与预处理器;支持编译缓存。

架构总览

DouPHP 采用“多入口 + 共享内核 + 模块化”的架构:

  • 入口层:三个独立入口分别承担前台页面、后台管理与 API 接口。
  • 内核层:bootstrap 统一完成环境、常量、自动加载、容器、门面、助手注册;Config 与 Module 提供运行时配置与模块开关。
  • 应用层:每端 Init 负责引导,Router 负责路由解析与调度,Dispatcher 执行中间件管道与控制器;Controller/Service/Model 实现业务;View/Template 渲染输出。
  • 扩展点:ProviderRegistry 注册 Provider;Module 动态加载业务模块;Plugin 目录承载支付、物流等插件;Theme 切换前端展示。
graph TB
R["请求"]
E1["前台入口"]
E2["后台入口"]
E3["API入口"]
B["核心引导 bootstrap"]
C["容器/门面/助手"]
G1["前台引导 Init"]
G2["后台引导 Init"]
G3["API引导 Init"]
RT1["前台路由 Router"]
RT2["后台路由 Router"]
RT3["API路由 Router"]
D["中央调度 Dispatcher"]
M["中间件管道"]
CO["控制器/服务/模型"]
V["视图/模板"]
J["JSON 响应"]
R --> E1
R --> E2
R --> E3
E1 --> B
E2 --> B
E3 --> B
B --> C
E1 --> G1 --> RT1
E2 --> G2 --> RT2
E3 --> G3 --> RT3
RT1 --> D
RT2 --> D
RT3 --> D
D --> M --> CO
CO --> V
CO --> J

详细组件分析

引导程序 Init 的工作流

  • 前台 Init::boot:会话与时区、根 URL、语言解析、核心对象实例化、Provider 注册、语言与模块加载、视图引擎装配、通用变量注入、站点关闭检查、异步对账兜底触发。
  • 后台 Init::boot:会话与时区、后台常量、核心对象实例化、云服务配置、Provider 注册、语言与模块加载、工作台/更新角标/主题设置 ViewModel、授权检测、JS 路由与语言脚本注入。
  • API Init::boot:会话与时区、API 常量、核心对象实例化、Provider 注册、语言与模块加载、授权检测、用户上下文与定价服务装配、站点关闭 JSON 响应。
sequenceDiagram
participant U as "客户端"
participant IN as "入口 index.php"
participant BS as "核心引导 bootstrap"
participant INIT as "Init : : boot"
participant RT as "Router : : dispatch"
participant DISP as "Dispatcher"
participant CTRL as "控制器/服务"
participant RESP as "响应发送"
U->>IN : HTTP 请求
IN->>BS : 加载核心引导
BS-->>IN : 容器/门面/助手就绪
IN->>INIT : boot()
INIT-->>IN : 引导完成
IN->>RT : dispatch()
RT->>DISP : run(DispatchPlan, Container)
DISP->>CTRL : 执行中间件与控制器
CTRL-->>RESP : 返回 Response/JSON
RESP-->>U : 发送响应

路由与调度

  • 前台路由:解析 route 字符串(已剥离语言前缀),生成 DispatchPlan;未命中返回 page_wrong 提示;命中后由 Dispatcher 执行并可能返回 Response。
  • 后台路由:位置解析 route 参数,未命中或方法不允许时重定向至首页并携带错误提示;命中后进入中间件管道执行。
  • API 路由:位置解析 route 参数,未命中或方法不允许时返回标准 JSON 错误;命中后进入中间件管道执行。
flowchart TD
Start(["入口 dispatch"]) --> Parse["解析路由<br/>Resolver -> DispatchPlan"]
Parse --> Check{"是否匹配?"}
Check -- 否 --> Err["端特定错误处理<br/>404/405/重定向/JSON"]
Check -- 是 --> Run["Dispatcher.run<br/>中间件+控制器"]
Run --> Resp{"是否返回 Response?"}
Resp -- 是 --> Send["send() 输出"]
Resp -- 否 --> End(["结束"])

响应与异常处理

  • 前台:DomainException 在 JSON 请求下返回业务错误;否则走 message 提示页;未捕获异常根据 site.debug 输出调试页或 JSON 500。
  • 后台:Ajax/JSON 请求返回 {ok:false, error};site.debug 开启时输出 HTML 调试;否则回退 page_wrong。
  • API:统一 ApiResponse 返回标准 JSON;site.debug 开启时输出调试 JSON;否则返回 SERVER_ERROR 500。
flowchart TD
Try["try 块执行"] --> Catch1{"HttpResponseException?"}
Catch1 -- 是 --> Send1["发送响应并退出"]
Catch1 -- 否 --> Catch2{"RedirectException?"}
Catch2 -- 是 --> Redirect["重定向并发送"]
Catch2 -- 否 --> Catch3{"DomainException?"}
Catch3 -- 是 --> DomainResp["端特定错误响应"]
Catch3 -- 否 --> Catch4{"Exception/Throwable"}
Catch4 -- 是 --> Uncaught["未捕获异常处理<br/>日志+调试/错误响应"]
Catch4 -- 否 --> End["结束"]

MVC 分层与模块化

  • Model:按模块组织(如 order、product、user),通过 ORM 访问数据库。
  • Service:封装领域逻辑,供 Controller 调用;部分服务通过 Module::make 按需加载。
  • Controller:接收请求、调用 Service、返回 Response 或视图。
  • View/Template:前后端分别装配 DouView,支持编译缓存与预处理器。
  • 模块化:features.* 控制模块启用;SystemBootstrap 加载 module/system/lang 清单;Module 动态解析业务类。

插件化扩展机制

  • 插件目录 plugin/:支付、物流、登录等插件以独立模块形式存在,遵循约定目录结构与接口契约。
  • 插件入口:可通过回调/通知 URL 直接调用 Init::bootForPluginEntry 完成必要初始化(数据库、语言、会话)。
  • 扩展点:ProviderRegistry 注册 Provider;Module 动态加载;Config 与 features 控制行为。

前台、后台、API 的差异与统一

  • 统一性:
    • 均通过 bootstrap 初始化核心环境与容器。
    • 均使用 Init::boot 进行引导,职责相似但侧重点不同。
    • 均使用 Router::dispatch 进行路由调度与异常处理。
  • 差异性:
    • 前台:关注多语言、主题、SEO、消息提示页、购物车角标等。
    • 后台:关注权限、菜单、工作台、主题设置、云服务等。
    • API:关注 JSON 响应、鉴权中间件、限流、最小化初始化。

依赖关系分析

  • 入口依赖 bootstrap:确保常量、自动加载、容器、门面、助手可用。
  • Init 依赖容器与 Provider:按需注册语言、模块、服务与视图引擎。
  • Router 依赖 Resolver 与 Dispatcher:将路由解析为可执行的计划并运行。
  • 响应体系:Response 基类被 ApiResponse、JsonResponse、view/redirect 助手复用。
graph LR
IN["入口"] --> BS["bootstrap"]
BS --> CTN["容器/门面"]
IN --> INIT["Init"]
INIT --> PRV["ProviderRegistry"]
INIT --> MOD["Module"]
IN --> RT["Router"]
RT --> RES["Resolver"]
RT --> DSP["Dispatcher"]
DSP --> CTRL["控制器/服务"]
CTRL --> RESP["Response/ApiResponse"]

性能考虑

  • 模板编译缓存:DouView 将编译结果写入 storage/cache/template/*,减少重复编译开销。
  • 模块与语言包按需加载:仅在 features 开启时加载对应模块与语言资源。
  • 异步兜底:前台支付对账抽签在 shutdown 钩子中执行,避免阻塞主请求。
  • 中间件管道:仅挂载必要中间件,减少请求链路开销。
  • 配置与常量一次性加载:bootstrap 阶段集中加载,避免重复 include。

故障排查指南

  • 前台未捕获异常:
    • 查看日志与 site.debug;JSON 请求返回标准错误;HTML 请求回退 page_wrong。
  • 后台未捕获异常:
    • Ajax/JSON 返回 {ok:false, error};site.debug 开启输出调试页;否则回退 page_wrong。
  • API 未捕获异常:
    • 统一 ApiResponse 返回 SERVER_ERROR 500;site.debug 开启输出调试 JSON。
  • 常见检查点:
    • 确认 bootstrap 已正确加载;容器与门面可用。
    • 确认 Init::boot 已完成;模块与语言包加载无误。
    • 确认路由解析成功;未命中时端特定错误处理是否正确。

结论

DouPHP 通过“多入口 + 共享内核 + 模块化”的架构,实现了前台、后台、API 的统一引导与差异化处理。核心引导 bootstrap 提供稳定的基础能力;Init 负责各端启动与装配;Router 与 Dispatcher 统一调度;Response 体系保证一致的输出语义。通过 Provider、Module、Plugin 与 Theme 的扩展点,系统具备良好的可扩展性与可定制性。性能方面借助模板编译缓存、按需加载与异步兜底优化了请求效率。

附录

  • 技术栈选择:
    • PHP 5.6+;PSR-4 自动加载;DI 容器;门面模式;模板引擎;ORM;中间件管道。
  • 依赖管理策略:
    • 容器单例与工厂;Provider 注册;Module 动态解析;Config 集中配置;features 开关控制。
  • 系统边界:
    • 入口层负责 HTTP 边界;内核层提供共享能力;应用层实现业务;存储层通过 ORM 访问数据库。
添加日期:2026-10-05