PHP 怎么架构守护

wen PHP项目 1

本文目录导读:

PHP 怎么架构守护

  1. 依赖与结构守护(防 “蜘蛛网”)
  2. 行为守护(防 “隐性破坏”)
  3. 破坏性变更守护(防 “兼容性灾难”)
  4. 演进与重构守护(防 “固化”)
  5. 实战建议:如何落地

在 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)。
  • 静态调用解析(PHPStan / Psalm 层级限制)
    • 利用 PHPStan 的 Strict Comparison 和自定义规则,禁止在业务逻辑层直接调用全局函数(如 file_get_contentsvar_dump),强制要求通过注入的服务(如 HttpClient)来操作。

行为守护(防 “隐性破坏”)

这一层守护的是“能跑”和“没跑错”的区别。

  • 契约测试(Contract Testing)

    针对多服务或微服务架构,使用工具(如 Pact)或 PHPUnit 的 Mockery,定义接口之间的契约,如果服务端修改了请求/响应结构,契约测试会立刻报错,防止“悄悄”破坏下游调用方。

  • 变异测试(Mutation Testing)
    • 工具:Infection。
    • 原理:它是个“破坏狂”,它会故意在你的代码里制造 Bug(例如把 if ($a > 10) 改成 if ($a >= 10),或者删除一行代码),然后跑你的单元测试。
    • 守护:如果变异后的代码依然能通过原有测试,说明该位置没有测试覆盖,测试的质量是“虚胖”的,架构守护要求核心逻辑的“变异得分”不低于 80%。
  • 系统的六边形架构测试(Architectural Test in PHPUnit)
    • 工具phppest/archazjezz/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 MigrationsDiff 模式对比实体映射和实际数据库结构,或使用工具 SchemaSpy 生成数据库结构差异报告,防止开发者手工改库导致生产环境无法同步。

演进与重构守护(防 “固化”)

架构不是一成不变的,守护也需要“动态”。

  • 死代码检测(Deptrac + PHPStan)
    • 通过 PHPStan 的 -l 最高级别,结合 phpstan-deprecation-rules,检测到某个接口或类已经标记为 @deprecated,那么凡是引用它的代码,在 CI 中都会收到警告。
    • 建议引入 Architecture Decision Records(ADR) 守护:每次重大的架构调整,必须在代码库的 /docs/adr 目录下新增一个 Markdown 文件,可以通过 CI 脚本校验每次 PR 修改了架构核心目录时,必须附带新的 ADR,否则阻断合并。

实战建议:如何落地

在 PHP 中架构守护最怕变成“一次性表演”,为了真正落地,建议按以下步骤操作:

  1. 以 CI 为唯一标准:将上述工具的检查全部集成到 GitLab CI 或 GitHub Actions 的 Pipeline 中(放在 test 阶段之前)。
  2. 引入质量门槛(Quality Gate)
    • 规模上:Deptrac 规则 0 违规。
    • 复杂度上:PHPStan 级别至少 level 6(建议 level 8),且自定义规则 max 10 个违规以内。
  3. 从小处开始,渐进式保护:对于老项目,不要一上来就全盘禁止,可以在 Deptrac 中定义 Legacy 层,允许其自由依赖,但规定“新代码不允许进入 Legacy 层”,这样既能推动重构,又不会阻断业务开发。
  4. 使用 PHP 8.1+ 特性:充分利用 readonly 属性和 enum,编译器层面就能阻止一部分“到处改对象属性”的架构污染,比运行时守护更早生效。

架构守护在 PHP 里,50% 靠工具(Deptrac、PHPStan、Infection),50% 靠纪律(CI 强制阻断)

对于中小型 PHP 团队,Deptrac(依赖方向)+ PHPStan(类型安全)+ PHPUnit(行为契约) 这三板斧是性价比最高的守护组合,它们能像雷达一样,在“代码腐化”刚冒出苗头时就发出警报,确保你能安心地接需求、写业务,而不用担心某一天系统突然因架构崩塌而需要重写。

抱歉,评论功能暂时关闭!