引言
本技术文档聚焦 DouPHP 小程序端与 Web 端的架构差异,围绕运行环境、框架结构、组件系统、生命周期管理、数据绑定、事件处理、运行时限制、路由系统与状态保持等维度进行对比说明。通过代码级分析与可视化图示,帮助开发者理解小程序的 Page-Component 模式与 Web 端 MVC 模式的对应关系,并给出适配关键点的实践指引。
项目结构
- Web 端(前台)入口位于根目录 index.php,负责初始化路由、异常处理与响应发送;后台入口位于 admin/index.php,提供管理端请求处理;前台控制器基类 front/controller/BaseController.php 统一视图渲染与 JSON/重定向分流。
- 小程序端位于 miniprogram/default,app.ts 为应用入口,app.json 声明页面、窗口与 TabBar;pages/index/index.ts 展示典型 Page 的生命周期、数据绑定与网络请求;utils/route.ts 提供命名路由生成能力,与后端路由表同步。
graph TB
subgraph "Web端"
WEntry["前台入口<br/>index.php"]
AEntry["后台入口<br/>admin/index.php"]
BaseCtrl["前台控制器基类<br/>BaseController.php"]
end
subgraph "小程序端"
MPApp["应用入口<br/>app.ts"]
MPConf["应用配置<br/>app.json"]
MPPage["首页页面<br/>pages/index/index.ts"]
MPRoute["命名路由工具<br/>utils/route.ts"]
end
WEntry --> BaseCtrl
AEntry --> BaseCtrl
MPApp --> MPConf
MPApp --> MPPage
MPPage --> MPRoute
图表来源
- index.php:16-44
- admin/index.php:17-40
- front/controller/BaseController.php:52-85
- miniprogram/default/app.ts:12-67
- miniprogram/default/app.json:1-178
- miniprogram/default/pages/index/index.ts:11-79
- miniprogram/default/utils/route.ts:21-65
章节来源
- index.php:16-75
- admin/index.php:17-63
- front/controller/BaseController.php:52-134
- miniprogram/default/app.ts:12-158
- miniprogram/default/app.json:1-178
- miniprogram/default/pages/index/index.ts:11-205
- miniprogram/default/utils/route.ts:21-65
核心组件
- Web 端
- 入口与路由:index.php 设置前台路由委托、解析语言前缀、执行 Init 引导、分发路由并发送响应;异常捕获后按 JSON/HTML 分支输出。
- 后台入口:admin/index.php 类似流程,但面向管理端,错误处理对 Ajax/JSON 有专门回退。
- 控制器基类:BaseController.php 提供 view() 渲染与 respond() 统一成功分流(JSON 返回 redirect_url,表单提交走 303)。
- 小程序端
- 应用入口:app.ts 注册全局 HTTP 拦截器、启动 Store、解析推广参数、自动更新、全局错误与页面未找到钩子。
- 页面与组件:app.json 声明 pages、window、tabBar、usingComponents;页面使用 Page 生命周期与 setData 驱动 UI。
- 路由工具:utils/route.ts 基于生成的路由表构建 URL,支持占位符替换与 query 拼接,兼容 rewrite_enable 开关。
章节来源
- index.php:16-75
- admin/index.php:17-63
- front/controller/BaseController.php:52-85
- miniprogram/default/app.ts:12-158
- miniprogram/default/app.json:1-178
- miniprogram/default/utils/route.ts:21-65
架构总览
小程序采用“应用-页面-组件”的 Page-Component 模式,数据流由 Store 与页面 data 双向驱动,事件通过小程序原生 API 触发;Web 端采用 MVC 模式,请求经路由到控制器,控制器渲染模板或返回 JSON,浏览器侧通过 DOM 与脚本交互。
sequenceDiagram
participant Client as "客户端"
participant MPApp as "小程序应用<br/>app.ts"
participant MPPage as "小程序页面<br/>pages/index/index.ts"
participant RouteTool as "路由工具<br/>utils/route.ts"
participant API as "后端API"
participant WebEntry as "Web入口<br/>index.php"
participant Ctrl as "控制器<br/>BaseController.php"
Client->>MPApp : 启动应用
MPApp->>MPApp : 初始化Store/拦截器/全局钩子
MPPage->>RouteTool : route('xxx', params)
RouteTool-->>MPPage : 生成URL
MPPage->>API : 发起HTTP请求
API-->>MPPage : 返回数据
MPPage->>MPPage : setData更新UI
Client->>WebEntry : 访问页面
WebEntry->>WebEntry : 解析路由/Init引导
WebEntry->>Ctrl : 分发到控制器
Ctrl-->>Client : 渲染模板或JSON响应
图表来源
- miniprogram/default/app.ts:12-67
- miniprogram/default/pages/index/index.ts:29-79
- miniprogram/default/utils/route.ts:21-65
- index.php:16-44
- front/controller/BaseController.php:52-85
详细组件分析
小程序端:应用与页面生命周期
- 应用生命周期
- onLaunch:注册 HTTP 错误拦截器、解析推广参数、引导全局 Store、计算导航栏高度、开启自动更新、调试期启用 vConsole。
- onShow:从后台切回时再次尝试解析推广参数。
- onError/onUnhandledRejection:全局 JS 异常与 Promise 拒绝记录,调试期弹窗提示。
- onPageNotFound:页面未找到记录与调试提示。
- 页面生命周期
- onLoad:设置标题、显示分享菜单、绑定 Store、发起首页数据请求、加载商品列表。
- onReady:恢复登录态,必要时跳转到工作区。
- onReachBottom:触底分页追加。
- 事件处理:分类切换、导航跳转、Tab 切换等通过 wx.* API 完成。
flowchart TD
Start(["应用启动"]) --> OnLaunch["onLaunch<br/>初始化/解析推广/引导Store"]
OnLaunch --> OnShow["onShow<br/>切前台再解析推广"]
OnShow --> PageLoad["页面onLoad<br/>绑定Store/请求数据"]
PageLoad --> Ready["onReady<br/>恢复登录/跳转工作区"]
Ready --> Bottom["onReachBottom<br/>分页追加"]
Bottom --> End(["页面结束"])
图表来源
- miniprogram/default/app.ts:23-67
- miniprogram/default/pages/index/index.ts:29-79
- miniprogram/default/pages/index/index.ts:166-175
章节来源
- miniprogram/default/app.ts:23-96
- miniprogram/default/pages/index/index.ts:29-79
- miniprogram/default/pages/index/index.ts:166-175
Web端:MVC 控制器与响应分流
- 入口与路由:index.php 设置路由委托、解析语言前缀、执行 Init、分发路由并发送响应;异常捕获后根据是否 JSON 请求选择错误响应或提示页。
- 控制器基类:BaseController.php 的 view() 合并布局变量,respond() 在期望 JSON 的请求中返回标准成功信封并附带 redirect_url,否则执行 303 重定向。
classDiagram
class BaseController {
+view(template, data, statusCode) ViewResponse
+respond(request, redirectUrl, data, message) Response
+layoutVars() array
+buildLinkUserCenter(currentModule) array
}
图表来源
- front/controller/BaseController.php:52-134
章节来源
- index.php:16-75
- front/controller/BaseController.php:52-134
小程序路由与参数传递
- 命名路由:utils/route.ts 基于 routes.generated.ts 生成 URL,支持占位符替换与 query 拼接;当 rewrite_enable 关闭时回退到 index.php?route= 形态。
- 页面跳转:pages/index/index.ts 中使用 wx.navigateTo/switchTab 进行页面跳转,并通过 setData 更新本地状态。
flowchart TD
Call["调用 route(name, params)"] --> Lookup["查找路由表"]
Lookup --> Replace{"存在占位符?"}
Replace -- 是 --> Fill["替换{key}为encodeURIComponent(val)"]
Replace -- 否 --> Query["拼接query参数"]
Fill --> Build["构建最终URL"]
Query --> Build
Build --> Return["返回URL供navigateTo/switchTab使用"]
图表来源
- miniprogram/default/utils/route.ts:21-65
- miniprogram/default/pages/index/index.ts:189-203
章节来源
- miniprogram/default/utils/route.ts:21-65
- miniprogram/default/pages/index/index.ts:189-203
数据绑定与事件处理对比
- 小程序
- 数据绑定:Page.data 与 setData 驱动 UI;Store 通过 mobx-miniprogram-bindings 绑定字段,实现响应式更新。
- 事件处理:通过微信小程序事件模型(如 onCategoryScroll、swiperbindchange)获取事件对象,更新 data。
- Web端
- 数据绑定:服务器端模板渲染,控制器将数据注入视图;前端通过 DOM 操作或脚本更新界面。
- 事件处理:浏览器事件模型,结合 AJAX/Fetch 与后端 JSON 接口交互。
章节来源
- miniprogram/default/pages/index/index.ts:11-79
- miniprogram/default/pages/index/index.ts:107-125
- front/controller/BaseController.php:52-85
运行时限制与约束
- 小程序
- 文件访问权限:受限于小程序文件系统沙箱,无法直接访问任意路径,需通过上传/下载 API 或云开发能力。
- 网络请求限制:仅允许 HTTPS 域名白名单,跨域由平台控制;建议统一通过 services/http.js 封装。
- 本地存储容量:wx.setStorageSync 等 API 有大小限制,应避免存储大对象;敏感信息建议使用安全存储或云端。
- 页面栈与跳转:wx.navigateTo/switchTab 有层级与类型限制,Tab 页面不可用 navigateTo 打开。
- Web端
- 文件访问:服务端可读写服务器文件系统,注意权限与安全;静态资源通过 CDN/缓存优化。
- 网络请求:浏览器同源策略与 CORS 配置;AJAX/Fetch 与后端 JSON 接口交互。
- 本地存储:localStorage/sessionStorage 容量有限且非持久化首选;重要状态应落库或会话层。
路由系统与状态保持对比
- 小程序
- 路由:app.json 声明 pages 与 tabBar;页面间跳转使用 wx.* API;命名路由通过 utils/route.ts 生成 URL。
- 状态保持:Page.data 与 Store 维持页面与全局状态;onUnload 中销毁绑定避免内存泄漏。
- Web端
- 路由:index.php 设置路由委托,Admin 与 Front 各自 Router;控制器方法映射到业务逻辑。
- 状态保持:Session/Cookie 维持用户态;模板渲染时注入公共变量;JSON 响应携带 redirect_url 供客户端跳转。
章节来源
- miniprogram/default/app.json:1-178
- miniprogram/default/pages/index/index.ts:59-63
- index.php:16-44
- front/controller/BaseController.php:77-85
依赖关系分析
- 小程序端依赖
- app.ts 依赖 stores、services、utils;页面依赖 route 工具与 http 服务;app.json 声明页面与组件。
- Web端依赖
- index.php 依赖 core/bootstrap.php 与路由;控制器基类依赖模板渲染与响应对象;后台入口独立于前台但共享核心。
graph LR
MPApp["app.ts"] --> Stores["stores/*"]
MPApp --> Services["services/*"]
MPApp --> Utils["utils/*"]
MPPage["pages/index/index.ts"] --> RouteTool["utils/route.ts"]
MPPage --> HttpSvc["services/http.ts"]
MPConf["app.json"] --> Pages["pages/*"]
WEntry["index.php"] --> CoreBoot["core/bootstrap.php"]
WEntry --> Router["Front Router"]
Ctrl["BaseController.php"] --> Template["TemplateRenderer"]
Ctrl --> Response["ViewResponse/ApiResponse"]
图表来源
- miniprogram/default/app.ts:5-10
- miniprogram/default/pages/index/index.ts:1-7
- miniprogram/default/app.json:1-178
- index.php:16-26
- front/controller/BaseController.php:52-85
章节来源
- miniprogram/default/app.ts:5-10
- miniprogram/default/pages/index/index.ts:1-7
- miniprogram/default/app.json:1-178
- index.php:16-26
- front/controller/BaseController.php:52-85
性能考量
- 小程序
- 首屏优化:onLaunch 中 bootstrapStores 实现秒开;按需加载数据,避免阻塞渲染。
- 滚动与动画:利用 wx.nextTick 与 SelectorQuery 计算视口宽度,减少重排。
- 网络优化:统一 http 服务封装,错误拦截与重试策略;合理使用缓存与分页。
- Web端
- 模板渲染:BaseController::view 合并 layoutVars 仅在需要时执行,降低开销。
- 响应分流:JSON 请求返回 redirect_url,减少二次请求;303 重定向保证无 JS 场景可用。
- 缓存与CDN:静态资源与图片通过 CDN 加速,数据库查询优化与索引。
故障排查指南
- 小程序
- 全局错误:app.ts 的 onError 与 onUnhandledRejection 记录异常,调试期弹窗提示;检查 console 与 vConsole。
- 页面未找到:onPageNotFound 记录 path,核对 app.json 与路由表。
- 网络错误:http 拦截器处理 UNAUTHORIZED 登出;检查域名白名单与接口签名。
- Web端
- 入口异常:index.php 与 admin/index.php 捕获 DomainException/HttpResponseException,按 JSON/HTML 分支输出;查看错误日志与调试页。
- 控制器错误:BaseController::respond 在 JSON 请求中返回标准信封;检查 redirect_url 与消息文案。
章节来源
- miniprogram/default/app.ts:69-96
- index.php:46-75
- admin/index.php:42-63
- front/controller/BaseController.php:77-85
结论
DouPHP 小程序端与 Web 端在架构上分别遵循 Page-Component 与 MVC 模式,前者强调应用-页面-组件的层次化结构与小程序原生 API 的事件驱动,后者侧重请求-控制器-模板的分层与响应分流。两者在路由、状态保持、数据绑定与事件处理上各有特点:小程序通过 Store 与 setData 实现响应式更新,Web 端通过模板与 JSON 响应实现前后端解耦。适配时需关注小程序的运行时限制(文件访问、网络、存储、页面栈),并利用命名路由工具与统一 HTTP 服务提升可维护性。
附录:适配要点与示例路径
- 小程序 Page-Component 与 Web MVC 对应关系
- 应用入口:小程序 app.ts vs Web index.php
- 页面与组件:小程序 pages/* vs Web 控制器与模板
- 路由:小程序 app.json + utils/route.ts vs Web 路由委托与控制器方法
- 状态:小程序 Store + Page.data vs Web Session + 模板变量
- 生命周期与数据绑定
- 小程序:onLaunch/onShow/onLoad/onReady/onReachBottom;setData 驱动 UI
- Web:Init 引导、控制器 view/respond;模板渲染与 JSON 响应
- 事件处理
- 小程序:wx.* 事件与自定义事件;setData 更新状态
- Web:浏览器事件模型;AJAX/Fetch 与后端接口交互
- 路由与参数传递
- 小程序:命名路由生成 URL;wx.navigateTo/switchTab 跳转
- Web:路由委托到控制器;JSON 响应携带 redirect_url
- 运行时限制
- 小程序:HTTPS 白名单、文件沙箱、存储容量、页面栈限制
- Web:CORS、服务器文件权限、缓存与 CDN
章节来源
- miniprogram/default/app.ts:12-158
- miniprogram/default/pages/index/index.ts:29-79
- miniprogram/default/utils/route.ts:21-65
- index.php:16-75
- front/controller/BaseController.php:52-85