Appearance
PHP 后端基础规范(API 服务)
1. 适用范围
本规范约束仓库内 PHP HTTP API 服务 的代码组织方式,当前落地目录为 services/api/。其它语言服务、仅文档/脚本不在此列。
与全局协作规则的关系:先遵守 AGENTS.md 与 docs/standards/开发规范.md,再遵守本文件;若本文件与架构文档冲突,以架构文档与任务文档为准并显式记录冲突。
2. 分层与职责(强制)
| 层次 | 位置(约定) | 职责 |
|---|---|---|
| 路由 | services/api/router/api.php(由 public/index.php 加载) | 仅声明 HTTP 方法、路径、控制器类与方法;不写业务逻辑。 |
| 控制器 | services/api/app/Controllers/ | 解析请求、调用下层、组装 HTTP 响应;保持薄,不写复杂领域规则。 |
| 数据访问 | services/api/app/Repositories/ | 封装对数据库、缓存、外部 HTTP 等 事实读写的边界;不承载业务流程编排。 |
| 业务逻辑 | services/api/app/Logic/(可按域分子目录,如 Logic/Api/) | 多步编排、跨 Repository、复杂校验、可复用领域过程 放在此处;入口鉴权类 App\Logic\Auth 亦属本层。 |
| 公共函数 | services/api/app/helper.php(Composer autoload.files 已加载) | 多处复用、与框架无关的纯函数或小工具(如解析请求头、格式化);避免把业务流程堆进 helper。 |
| 框架/基础设施 | services/api/lib/ | 请求/响应、路由、异常、缓存等 与业务无关 的通用能力。 |
3. 新增接口的强制顺序
- 在
router/api.php注册路由(Route::get/post/...),路径与Lib\Route的 URI 规则一致(注意Route::group前缀,完整路径形如api/...)。 - 实现或扩展控制器(通常
App\Controllers\Api\*)。 - 需要持久化或外部数据时,在
Repositories增加或复用方法,由 Logic 或控制器调用。 - 当单接口内分支多、步骤多、或两处以上控制器要复用同一套规则时,将过程抽到
Logic(必要时拆类),控制器只保留一行或数行调用。 - 当同一纯逻辑在多个类/层出现(例如解析
Authorization: Bearer),抽到helper.php或小的 Logic 辅助类,禁止复制粘贴。
4. 控制器书写约定
- 简单逻辑(参数读取、一次 Repository 调用、固定 JSON 形状)可直接写在控制器方法内。
- 复杂逻辑必须下沉到
Logic,控制器仅负责:jsonBody()/getAttr/ 调用 Logic、返回Response或数组。 - 需登录的 JSON API 可复用
App\Controllers\Api\Concerns\JsonApiTrait(如handleJsonAction、requirePortalAccount)。 - 禁止在控制器中直接写 SQL;禁止在 Repository 中写与 HTTP 强耦合的代码。
5. 鉴权与用户上下文(强制)
- 统一入口:需鉴权的 API 控制器应继承
App\Controllers\BaseApiController,在beforeHook()中通过App\Logic\Auth::check()完成校验;未通过则abort401(),不进入 Action。 - 白名单:免登录路径在
BaseApiController的$withoutAuth中维护,值为 去掉前导/的路径(与Request::$uri对齐),例如api/auth/login。 - 鉴权结果写入 Request:
Auth校验成功后通过Request::setAttr()注入,控制器与 Logic 通过Request::getAttr()读取,禁止在业务控制器构造函数中重复组装一套“只为取当前用户”的会话对象。 - 约定键名(与 JSON body 共用存储,勿与客户端字段冲突):
App\Logic\Auth::ATTR_USER_ID:当前用户主键(Legacy Token 与门户均可能写入)。App\Logic\Auth::ATTR_PORTAL_ACCOUNT:门户登录后的 账号表行(array);控制器侧可使用JsonApiTrait::requirePortalAccount()。
- Legacy 与门户并存时,以
Auth::check()的实现为准(例如先Token头 /token查询参数,再Authorization: Bearer);新增方式应扩展Auth,而不是在控制器里平行判断。
6. helper.php 使用原则
- 适合:无状态字符串/数组处理、可单元测试的解析函数、与具体业务表无关的通用工具(如
parse_authorization_bearer())。 - 不适合:依赖大量全局状态、长业务流程、仅单接口使用一次的代码(留在控制器或 Logic 即可)。
7. 自检清单(提交前)
- [ ] 新接口是否已出现在
router/api.php? - [ ] 是否避免在 Repository 外直接访问数据库连接?
- [ ] 复杂逻辑是否已从控制器挪到
Logic? - [ ] 多处重复的片段是否已抽到
helper或 Logic? - [ ] 需登录接口是否继承
BaseApiController,且未在 Action 内重复鉴权? - [ ] 写入
Request的内部键是否使用Auth常量或团队约定前缀,避免与 body 字段撞名?
8. 变更与回写
修改本规范约定的目录职责或鉴权链时,应同步检查:
services/api/README.md(若存在服务级说明)changelogs/中相关条目- 任务文档中的验收说明
9. 版本说明
- 2026-04:初版,与当前
services/api路由、基类鉴权、Auth+Request注入方式对齐。