简介
本规范面向 DouPHP 框架的插件开发者,统一说明插件在 plugin 目录下的组织方式、配置文件 manifest.php 的必需字段、Provider 类的命名与实现要求、Service 层的业务封装方法,并针对支付、物流、社交登录三类插件给出差异化的目录结构与最佳实践。目标是让插件具备一致的可发现性、可配置性与可扩展性,便于系统自动加载、管理生命周期与扩展能力。
项目结构
DouPHP 将第三方或内置扩展以“插件”形式组织在根目录下的 plugin 文件夹中。每个插件是一个独立子目录,包含描述信息、入口 Provider、业务 Service、可选 SDK 与资源等。
graph TB
A["plugin 根目录"] --> B["alipay支付"]
A --> C["wxpay支付"]
A --> D["google社交登录"]
A --> E["wxlogin社交登录"]
A --> F["ems物流"]
B --> B1["manifest.php"]
B --> B2["AlipayProvider.php"]
B --> B3["AlipayService.php"]
B --> B4["sdk/..."]
C --> C1["manifest.php"]
C --> C2["WxpayProvider.php"]
C --> C3["WxpayService.php"]
D --> D1["manifest.php"]
D --> D2["GoogleProvider.php"]
D --> D3["GoogleService.php"]
E --> E1["manifest.php"]
E --> E2["WxloginProvider.php"]
E --> E3["WxloginService.php"]
F --> F1["manifest.php"]
F --> F2["EmsProvider.php"]
F --> F3["EmsService.php"]
图示来源
- plugin/alipay/manifest.php:7-10
- plugin/wxpay/manifest.php:7-10
- plugin/google/manifest.php:7-10
- plugin/ems/EmsProvider.php:38-69
章节来源
- plugin/alipay/manifest.php:1-11
- plugin/wxpay/manifest.php:1-11
- plugin/google/manifest.php:1-11
核心组件
- 插件清单 manifest.php:声明插件分组与 Provider 类名,供系统注册与发现。
- Provider 类:实现框架定义的接口,暴露插件元数据与能力入口(如 start/notify/finish/query 或 methods)。
- Service 类:承载具体业务逻辑,调用第三方 SDK、数据库、消息队列等,保持 Provider 薄而稳定。
关键要点
- manifest.php 必须返回数组,包含 plugin_group 与 provider 两个键。
- Provider 需实现对应接口,提供 pluginId()、meta() 以及能力相关方法。
- Service 通过依赖注入获取 PaymentService、DB、配置等基础设施,避免硬编码。
章节来源
- plugin/alipay/AlipayProvider.php:15-110
- plugin/alipay/AlipayService.php:20-229
- plugin/google/GoogleProvider.php:13-99
- plugin/wxlogin/WxloginProvider.php:13-95
- plugin/ems/EmsProvider.php:11-71
架构总览
插件通过 manifest.php 向系统注册自身分组与 Provider;系统根据分组加载对应的 Provider 接口契约;Provider 作为门面,委托 Service 完成实际业务。
sequenceDiagram
participant Sys as "系统"
participant Reg as "插件注册器"
participant Prov as "Provider"
participant Svc as "Service"
participant Ext as "外部服务/SDK"
Sys->>Reg : 扫描 plugin 目录
Reg->>Reg : 读取 manifest.php
Reg-->>Sys : 返回 {plugin_group, provider}
Sys->>Prov : 实例化 Provider
Sys->>Prov : 调用 meta()/pluginId()
Note over Prov,Svc : Provider 仅做参数校验与转发
Sys->>Svc : 调用业务方法(start/notify/finish/query/methods)
Svc->>Ext : 调用第三方SDK/接口
Ext-->>Svc : 返回结果
Svc-->>Sys : 标准化结果
图示来源
- plugin/alipay/manifest.php:7-10
- plugin/alipay/AlipayProvider.php:31-110
- plugin/alipay/AlipayService.php:44-172
详细组件分析
支付插件(以 alipay 为例)
-
目录结构
- manifest.php:声明 plugin_group=payment,provider 指向 AlipayProvider。
- AlipayProvider.php:实现 ReconcilablePaymentProviderInterface,提供 pluginId、meta、start、notify、finish、query。
- AlipayService.php:封装支付宝 SDK 调用、回调验签、状态推进与对账查询。
- sdk/:第三方 SDK 与页面跳转所需构建器。
-
关键流程
- 发起支付:Provider.start -> Service.start -> 生成支付表单/链接。
- 异步通知:Provider.notify -> Service.notify -> 验签 -> 标记成功。
- 同步回调:Provider.finish -> Service.finish -> 验签 -> 标记成功 -> 发送邮件。
- 主动对账:Provider.query -> Service.query -> 查询交易状态 -> 返回标准结果。
sequenceDiagram
participant Client as "客户端"
participant Prov as "AlipayProvider"
participant Svc as "AlipayService"
participant PaySrv as "PaymentService"
participant Ali as "支付宝SDK"
Client->>Prov : start(PaymentRequest)
Prov->>Svc : start(request)
Svc->>Ali : pagePay(构造请求)
Ali-->>Client : 返回支付页URL
Ali-->>Prov : notify(payload)
Prov->>Svc : notify(payload)
Svc->>PaySrv : markSucceeded(paymentSn, tradeNo, raw)
Ali-->>Prov : finish(payload)
Prov->>Svc : finish(payload)
Svc->>PaySrv : markSucceeded(...)
Svc-->>Prov : 重定向到订单页
图示来源
- plugin/alipay/AlipayProvider.php:75-110
- plugin/alipay/AlipayService.php:44-120
章节来源
- plugin/alipay/manifest.php:7-10
- plugin/alipay/AlipayProvider.php:15-110
- plugin/alipay/AlipayService.php:20-229
- core/infra/plugin/contract/ReconcilablePaymentProviderInterface.php
物流插件(以 ems 为例)
-
目录结构
- manifest.php:声明 plugin_group=shipping,provider 指向 EmsProvider。
- EmsProvider.php:实现 ShippingPluginProviderInterface,提供 pluginId、meta、methods。
- EmsService.php:计算运费、包邮规则、可选地对接物流查询。
-
设计要点
- meta.config 用于后台配置费用与包邮门槛。
- methods 返回可用配送方式列表,供下单时选择。
flowchart TD
Start(["进入物流选择"]) --> Meta["读取 EmsProvider.meta()"]
Meta --> Config["解析配置: 费用/包邮门槛"]
Config --> Methods["EmsService.methods() 计算可用方式"]
Methods --> Return["返回配送方式列表"]
图示来源
- plugin/ems/EmsProvider.php:38-69
章节来源
- plugin/ems/EmsProvider.php:11-71
- core/infra/plugin/contract/ShippingPluginProviderInterface.php
社交登录插件(以 google、wxlogin 为例)
-
目录结构
- manifest.php:声明 plugin_group=connect,provider 指向对应 Provider。
- GoogleProvider.php / WxloginProvider.php:实现 ConnectPluginProviderInterface,提供 pluginId、meta、start、finish。
- GoogleService.php / WxloginService.php:处理 OAuth 授权、code 换 token、拉取用户信息、账号绑定/注册。
-
关键流程
- 开始授权:Provider.start -> Service.start -> 生成授权 URL。
- 回调处理:Provider.finish -> Service.finish -> code 换 token -> 获取用户信息 -> 登录/注册。
sequenceDiagram
participant User as "用户"
participant Prov as "GoogleProvider/WxloginProvider"
participant Svc as "GoogleService/WxloginService"
participant OA as "OAuth提供商"
User->>Prov : start(request)
Prov->>Svc : start(request)
Svc->>OA : 跳转授权页
OA-->>Prov : finish(payload)
Prov->>Svc : finish(payload)
Svc->>OA : code换token/获取用户信息
OA-->>Svc : 用户信息
Svc-->>Prov : 登录成功/注册完成
图示来源
- plugin/google/GoogleProvider.php:81-99
- plugin/wxlogin/WxloginProvider.php:77-95
章节来源
- plugin/google/manifest.php:7-10
- plugin/google/GoogleProvider.php:13-99
- plugin/wxlogin/WxloginProvider.php:13-95
- core/infra/plugin/contract/ConnectPluginProviderInterface.php
依赖关系分析
- 插件通过 manifest.php 声明分组与 Provider,系统据此加载对应接口契约。
- Provider 依赖 Service,Service 依赖框架基础服务(如 PaymentService、DB、配置)。
- 不同插件类型实现不同接口,形成松耦合扩展点。
graph LR
M["manifest.php"] --> P["Provider"]
P --> I["接口契约"]
P --> S["Service"]
S --> Core["框架服务/SDK"]
图示来源
- plugin/alipay/manifest.php:7-10
- plugin/alipay/AlipayProvider.php:15-110
- plugin/alipay/AlipayService.php:20-229
- core/infra/plugin/contract/ReconcilablePaymentProviderInterface.php
- core/infra/plugin/contract/ShippingPluginProviderInterface.php
- core/infra/plugin/contract/ConnectPluginProviderInterface.php
章节来源
- plugin/alipay/AlipayProvider.php:15-110
- plugin/alipay/AlipayService.php:20-229
- plugin/google/GoogleProvider.php:13-99
- plugin/wxlogin/WxloginProvider.php:13-95
- plugin/ems/EmsProvider.php:11-71
性能与可靠性考虑
- 支付插件
- 使用 PaymentService 统一推进支付状态机,减少重复逻辑与竞态。
- 对账查询应幂等,避免重复入账;异常时返回标准失败结果。
- 回调验签失败直接拒绝,防止伪造通知。
- 物流插件
- 运费计算尽量缓存配置与规则,避免频繁 IO。
- 对外部物流查询进行超时与重试控制。
- 社交登录插件
- 网络请求设置合理超时与错误码映射。
- 用户信息拉取失败时给出友好提示,支持回退策略。
故障排查指南
- 插件未生效
- 检查 manifest.php 是否返回 plugin_group 与 provider。
- 确认 provider 类名与命名空间正确,且实现了相应接口。
- 支付回调失败
- 核对 notify_url/return_url 是否正确配置。
- 检查验签逻辑与签名算法是否与 SDK 一致。
- 登录回调异常
- 检查 client_id/client_secret 与重定向地址是否匹配。
- 查看 code 换 token 的网络响应与错误码。
章节来源
- plugin/alipay/AlipayService.php:44-120
- plugin/google/GoogleProvider.php:50-79
- plugin/wxlogin/WxloginProvider.php:40-75
结论
遵循本规范可实现插件的统一注册、清晰分层与稳定扩展。manifest.php 负责声明,Provider 负责契约与编排,Service 专注业务实现。不同类型插件按约定组织目录与方法,既保证一致性,又保留灵活性。
附录:插件模板与最佳实践
标准插件目录模板
- 根目录:plugin/{your_plugin}/
- 必需文件
- manifest.php:声明 plugin_group 与 provider。
- XxxProvider.php:实现对应接口,提供 pluginId、meta、能力方法。
- XxxService.php:实现业务逻辑,调用 SDK/框架服务。
- 可选文件
- sdk/:第三方 SDK。
- images/、js/、css/:静态资源。
- 其他辅助类与工具。
章节来源
- plugin/alipay/manifest.php:7-10
- plugin/alipay/AlipayProvider.php:15-110
- plugin/alipay/AlipayService.php:20-229
manifest.php 配置格式与必需字段
- 必需字段
- plugin_group:插件分组,如 payment、shipping、connect。
- provider:Provider 类的完全限定类名。
- 示例参考
- 支付分组:见 alipay、wxpay。
- 连接分组:见 google。
章节来源
- plugin/alipay/manifest.php:7-10
- plugin/wxpay/manifest.php:7-10
- plugin/google/manifest.php:7-10
Provider 类命名规范与实现要求
- 命名
- 类名:{主题}Provider,位于命名空间 Dou\Plugin{主题}。
- 文件名:{主题}Provider.php。
- 实现
- 实现对应接口(支付/物流/连接)。
- 提供 pluginId() 唯一标识。
- 提供 meta() 描述名称、版本、分组、允许客户端、配置项。
- 提供能力方法(如 start/notify/finish/query 或 methods),内部委托 Service。
章节来源
- plugin/alipay/AlipayProvider.php:15-110
- plugin/ems/EmsProvider.php:11-71
- plugin/google/GoogleProvider.php:13-99
- plugin/wxlogin/WxloginProvider.php:13-95
Service 类业务逻辑封装方法
- 职责
- 封装第三方 SDK 调用、参数组装、回调验签、状态推进、日志记录。
- 使用框架服务(如 PaymentService、DB、配置)完成持久化与通知。
- 建议
- 输入输出使用 DTO(如 PaymentRequest、PaymentCallbackPayload)。
- 对外错误统一转换为标准结果对象(如 PaymentQueryResult)。
- 敏感配置从插件配置中读取,避免硬编码。
章节来源
- plugin/alipay/AlipayService.php:20-229
不同类型插件的目录差异
- 支付插件
- 典型文件:manifest.php、XxxProvider.php、XxxService.php、sdk/。
- 能力:start、notify、finish、query(可选)。
- 参考:alipay、wxpay。
- 物流插件
- 典型文件:manifest.php、XxxProvider.php、XxxService.php。
- 能力:methods(返回配送方式与费用)。
- 参考:ems。
- 社交登录插件
- 典型文件:manifest.php、XxxProvider.php、XxxService.php。
- 能力:start、finish(OAuth 授权与回调)。
- 参考:google、wxlogin。
章节来源
- plugin/alipay/manifest.php:7-10
- plugin/wxpay/manifest.php:7-10
- plugin/ems/EmsProvider.php:38-69
- plugin/google/manifest.php:7-10
- plugin/wxlogin/WxloginProvider.php:40-75
最佳实践
- 保持 Provider 薄层,复杂逻辑下沉至 Service。
- 所有外部调用增加超时、重试与错误处理。
- 使用统一的 DTO 与结果对象,确保跨插件一致性。
- 配置项通过 meta.config 暴露,便于后台可视化配置。
- 对账与回调需幂等,避免重复处理。
- 日志记录关键步骤与异常堆栈,便于定位问题。