接手祖传 PHP 项目别急着重写:一份渐进式改造路线图(附自查清单)

2 阅读1分钟

这篇文章写给刚接手"祖传 PHP 单体"的人:没有文档、没人敢动、每次上线都心惊胆战。过去多年我改造过多个这类系统(ecshop 式魔法全局变量、ThinkPHP 3 老项目、Smarty 模板混 SQL 的都有),总结出一条核心原则:先续命,再现代化;永远渐进式,不推倒重写。

第 0 步:先体检,再动手(1-2 周)

改造前必答的 5 个自查问题:

  1. 入口清单:有多少个对外 HTTP 入口?CLI 定时任务有哪些?(grep -r "$_GET\|$_POST" --include="*.php" | wc -l 只是开始)
  2. 数据库现状:多少张表?有多少存储过程/触发器/外键?有没有表没有任何代码引用(死表)?
  3. 依赖存亡:composer.json 里有多少个已停止维护的包?PHP 版本离 EOL 还有几个月?
  4. 部署方式:是手工 FTP 上传还是有 CI/CD?回滚需要多久?
  5. 测试覆盖:除了 php -l 语法检查,还有没有任何自动化测试?

把这 5 个答案写成一页纸,这就是你的改造基线。没有基线的改造 = 蒙眼开刀。

第 1 步:续命三件套(不改业务代码)

  • 上版本控制 + CI:哪怕只是 git + 每次提交跑 php -l + composer validate。手工 FTP 上传的时代必须先结束。
  • 加监控:错误日志聚合(Sentry 免费档够用)+ 慢查询日志打开 + 基本的存活探针。改造期间你会需要知道"是我改坏的还是本来就坏"。
  • 包一层 Smoke 测试:把 TOP 20 高频用户路径用脚本录下来(curl 也行),每次部署后跑一遍。这就是你最初的"防护网",比单元测试性价比高 10 倍。

第 2 步:绞杀者模式(Strangler Fig),不是重写

  • 新需求一律写到新的分层结构里(哪怕还是同一个 PHP 项目:路由层 → Service 层 → Repository 层),老代码只在被迫修改时才动
  • 老入口统一加一个薄 Front Controller,为将来按 URL 逐步分流做准备
  • 鉴权先统一:老系统常见的"每个页面自己查 session"必须先收口成一个中间件,否则新老系统永远接不通

第 3 步:数据层是最后的战场,也是最不能先动的

  • 先做只读收敛:所有 SQL 从页面代码里挪到统一的 DAO/Repository 类(可以用正则+人工复核批量做)
  • 不急着拆库。跨库事务的复杂度会立刻吃掉你全部收益
  • 真要拆:先按"读扩散"拆(新系统只读老库),写路径最后切换

第 4 步:退出判据

改造不是无限工程。满足以下任一条就可以停:

  • 新需求 100% 落在新结构里,老代码只读不改
  • 老代码占比 < 30% 且仍在收缩
  • 系统寿命预期 < 改造收益周期(这种情况直接封版续命更划算)

以上是完整路线图的骨架。《PHP 遗留系统改造路线图》(完整版:每步的操作清单、踩坑实录、工具选型对比,持续更新)我整理成了册,一次买断 ¥19.9 永久有效;配套还有《Go 高并发避坑清单》(¥9.9 买断)。都在我的爱发电店铺:afdian.com/a/standsun ,购买后可在评论区直接提问(工作日 24h 内回复)。