本文目录导读:

在 PHP 中,“架构守护”不仅仅是写几个单元测试,它更是一套工程实践、自动化工具与编码规范的结合,它的核心目的是防止系统在长期迭代中腐化(如代码耦合失控、循环依赖、违反分层原则),确保代码始终符合预先设计的架构蓝图。
要架构守护 PHP 项目,你可以从以下四个维度构建防御体系:
依赖与结构守护(防 “蜘蛛网”)
这是最核心的守护,防止代码变成“意大利面条”。
- 依赖方向守护(Deptrac):
- 工具:Deptrac 是 PHP 领域最强大的架构守护工具。
- 原理:你可以在 YAML 配置文件中定义“层”和“规则”。
Controller层可以依赖Service层,但Service层绝对不能依赖Controller层;Domain层不能被基础设施层反向依赖。 - 守护:在 CI(持续集成)中运行
vendor/bin/deptrac analyze,如果某天有人为了省事在 Service 里直接new了一个 Controller,CI 会直接报错并阻断合并。
- 循环依赖检测(Composer):
- 利用 Composer 的
composer diagnose或专门的分析脚本,检测包与包之间(或模块与模块之间)是否存在循环引用(A 依赖 B,B 又依赖 A)。
- 利用 Composer 的
- 静态调用解析(PHPStan / Psalm 层级限制):
- 利用 PHPStan 的 Strict Comparison 和自定义规则,禁止在业务逻辑层直接调用全局函数(如
file_get_contents、var_dump),强制要求通过注入的服务(如HttpClient)来操作。
- 利用 PHPStan 的 Strict Comparison 和自定义规则,禁止在业务逻辑层直接调用全局函数(如
行为守护(防 “隐性破坏”)
这一层守护的是“能跑”和“没跑错”的区别。
- 契约测试(Contract Testing):
针对多服务或微服务架构,使用工具(如 Pact)或 PHPUnit 的 Mockery,定义接口之间的契约,如果服务端修改了请求/响应结构,契约测试会立刻报错,防止“悄悄”破坏下游调用方。
- 变异测试(Mutation Testing):
- 工具:Infection。
- 原理:它是个“破坏狂”,它会故意在你的代码里制造 Bug(例如把
if ($a > 10)改成if ($a >= 10),或者删除一行代码),然后跑你的单元测试。 - 守护:如果变异后的代码依然能通过原有测试,说明该位置没有测试覆盖,测试的质量是“虚胖”的,架构守护要求核心逻辑的“变异得分”不低于 80%。
- 系统的六边形架构测试(Architectural Test in PHPUnit):
- 工具:
phppest/arch或azjezz/psl。 - 在测试套件里写伪代码断言,验证代码的“形状”。“所有 Repository 接口必须在
Infrastructure命名空间内”、“所有 Controller 类名必须以Controller。
- 工具:
破坏性变更守护(防 “兼容性灾难”)
PHP 动态类型特性容易导致参数变更引起隐性错误。
- Backward Compatibility(BC)检查:
- 工具:Roave Backward Compatibility Check。
- 原理:在 CI 中对比当前分支与上次发布 Tag 的差异(Diff)。
- 守护:如果有人给某个公开方法加了参数,或者把方法
protected改成了private,该工具会输出“此为破坏性变更”,强制开发者写升级迁移文档(UPGRADE.md),或者显式地同意变更。
- 数据库 Schema 守护:
- 不依赖
php artisan migrate:status(因为本地库可能不一致),使用 Doctrine Migrations 的Diff模式对比实体映射和实际数据库结构,或使用工具SchemaSpy生成数据库结构差异报告,防止开发者手工改库导致生产环境无法同步。
- 不依赖
演进与重构守护(防 “固化”)
架构不是一成不变的,守护也需要“动态”。
- 死代码检测(Deptrac + PHPStan):
- 通过 PHPStan 的
-l最高级别,结合phpstan-deprecation-rules,检测到某个接口或类已经标记为@deprecated,那么凡是引用它的代码,在 CI 中都会收到警告。 - 建议引入 Architecture Decision Records(ADR) 守护:每次重大的架构调整,必须在代码库的
/docs/adr目录下新增一个 Markdown 文件,可以通过 CI 脚本校验每次 PR 修改了架构核心目录时,必须附带新的 ADR,否则阻断合并。
- 通过 PHPStan 的
实战建议:如何落地
在 PHP 中架构守护最怕变成“一次性表演”,为了真正落地,建议按以下步骤操作:
- 以 CI 为唯一标准:将上述工具的检查全部集成到 GitLab CI 或 GitHub Actions 的 Pipeline 中(放在
test阶段之前)。 - 引入质量门槛(Quality Gate):
- 规模上:Deptrac 规则
0违规。 - 复杂度上:PHPStan 级别至少
level 6(建议level 8),且自定义规则max 10个违规以内。
- 规模上:Deptrac 规则
- 从小处开始,渐进式保护:对于老项目,不要一上来就全盘禁止,可以在 Deptrac 中定义
Legacy层,允许其自由依赖,但规定“新代码不允许进入 Legacy 层”,这样既能推动重构,又不会阻断业务开发。 - 使用 PHP 8.1+ 特性:充分利用
readonly属性和enum,编译器层面就能阻止一部分“到处改对象属性”的架构污染,比运行时守护更早生效。
架构守护在 PHP 里,50% 靠工具(Deptrac、PHPStan、Infection),50% 靠纪律(CI 强制阻断)。
对于中小型 PHP 团队,Deptrac(依赖方向)+ PHPStan(类型安全)+ PHPUnit(行为契约) 这三板斧是性价比最高的守护组合,它们能像雷达一样,在“代码腐化”刚冒出苗头时就发出警报,确保你能安心地接需求、写业务,而不用担心某一天系统突然因架构崩塌而需要重写。