遗留 PHP 应用往往是软件版本的"扩建过十几次的老楼":它能运行,业务依赖它,却没人愿意去碰。老旧的 PHP 版本、没有测试、职责混杂,以及多年累积的临时凑合,让每一次改动都充满风险。好消息是,遗留 PHP 现代化并不需要一次性的彻底重写,而后者通常是所有选项中风险最高的一个。本指南给出一条更安全、循序渐进的路径。

要点速览(TL;DR)

  • 彻底重写是最诱人也最危险的选项;渐进式现代化更安全,并能更早交付价值
  • 先从评估代码、升级到受支持的 PHP 版本,以及围绕关键行为搭建一张测试安全网开始
  • 引入 Composer、自动加载与现代化结构,然后朝着清晰的职责分离进行重构
  • 使用 strangler fig 模式逐步采用 Symfony 等框架,一块一块地替换旧系统

为什么不干脆重写?

从零开始重写很有吸引力:一张白纸,一切都是现代的。但这也正是大多数遗留现代化努力折戟的地方。重写意味着要重新实现多年来未被记录的业务规则,在构建期间冻结对线上系统的改进,并把整个业务押在一次性切换上。渐进式现代化通过以受控的步骤改进正在运行的系统、并在过程中持续交付价值来避免这一点。正是这一逻辑,使 strangler fig 方法成为大型机现代化 的默认选择:保留能用的部分,有目的地替换。

第 1 步:动手之前先评估

  • 盘点 PHP 版本、各项依赖及其支持状态。
  • 识别关键路径(业务不能失去的功能)以及风险最高、改动最频繁的区域。
  • 梳理明显的问题:散落在模板各处的 SQL、缺乏职责分离、全局状态、死代码。
  • 理解数据库,以及代码与它耦合得有多紧。

你无法安全地现代化自己并不理解的东西。

第 2 步:迁移到受支持的 PHP 版本

运行一个已到生命周期终点(EOL)的 PHP 版本是一种安全与性能上的负担,并且会阻碍现代化工具。

  • 逐个版本地渐进升级,而不是一次跨越多个版本。
  • 在每一步修复弃用项和破坏性变更。
  • 现代 PHP 比旧版本快得多也安全得多,因此仅凭性能,这一步往往就能收回成本。

第 3 步:搭建一张测试安全网

在任何遗留项目中,最有价值的投资都是围绕现有行为编写的测试。

  • 在改动任何东西之前,添加 characterisation tests,捕获系统当前的行为,尤其是在关键路径上。
  • 即便是粗粒度、高层次的测试,也能给你足够的信心去重构,而不会在无声无息中破坏东西。
  • 正是这套测试,使得后续每一步都变得安全。

第 4 步:引入现代化基础

  • 采用 Composer 进行依赖管理,采用 PSR-4 autoloading 取代手动的 include
  • 引入 namespaces 和合理的目录结构。
  • 添加 static analysis 和编码规范工具,以阻止新的债务不断累积。

第 5 步:朝清晰分离进行重构

  • 将业务逻辑与展现层和数据访问分离;把 SQL 从模板中移出去。
  • 抽取可复用的服务,并在能降低耦合的地方引入 dependency injection。
  • 以小而经过测试的步骤进行重构,而不是一次性大刀阔斧地重写整块区域。

第 6 步:逐步采用框架(Strangler Fig)

不要整体重写进一个框架,而应让新系统围绕旧系统生长。

  • 在遗留应用旁边搭起一个现代框架,例如 Symfony
  • 让新功能以及逐步迁移过来的功能经由该框架路由,同时让遗留代码继续服务其余部分。
  • 一块一块地替换旧功能,直到遗留代码被"绞杀"殆尽、可以退役为止。

这能让业务全程保持运行,并避免重写那种"全有或全无"的风险。(关于框架选型的对比,参见 2026 年 Symfony 与 Laravel 之争 。)

管理技术债务

现代化在其核心就是有意识地偿还技术债务。与其试图修复一切,不如优先处理真正让你付出代价的债务(你经常改动的代码、容易出问题的部分、安全风险)。若需更完整的论述,请参见面向工程团队的技术债务 指南。

关键要点

  • 遗留 PHP 现代化应避免一次性彻底重写;渐进式现代化以降低风险并更早交付价值。
  • 先评估,再升级到受支持的 PHP 版本,并围绕现有行为补充测试。
  • 分步引入 Composer、自动加载和清晰的职责分离。
  • 使用 strangler fig 模式采用 Symfony 等框架,一块一块地让遗留代码退役。

携手专家进行遗留 PHP 现代化

遗留现代化既是编码,也同样是风险管理。若要为此聘请一位 Symfony 开发者 ,Mecanik 会以整洁架构和渐进式方法,将遗留 PHP 代码库提升到现代、可维护、经过充分测试的标准,并借助 CI/CD 让质量随时间保持稳定。

常见问题(FAQ)

我应该重写还是重构一个遗留 PHP 应用? 在几乎所有情况下都应渐进式重构。彻底重写意味着重新实现多年来未被记录的业务规则,并把业务押在一次性切换上,而这正是大多数努力折戟之处。渐进式现代化以受控且有价值的步骤改进正在运行的系统。

现代化遗留 PHP 的第一步是什么? 评估代码、依赖和 PHP 版本,然后升级到受支持的 PHP 版本,并围绕关键的现有行为补充测试。正是这张测试安全网,使后续每一步重构都变得安全。

如何在不重写的情况下把遗留 PHP 迁移到框架? 使用 strangler fig 模式:在遗留应用旁边搭起一个现代框架,例如 Symfony,让新功能和已迁移功能经由它路由,并一块一块地替换旧功能,直到遗留代码可以退役。业务全程保持运行。

为什么升级 PHP 版本很重要? 运行一个已到生命周期终点的 PHP 版本是一种安全与性能风险,并会阻碍现代化工具。更新的 PHP 明显更快也更安全,因此升级往往能立即改善性能,并解锁现代化所依赖的库和工具。

如何应对一个完全没有测试的遗留应用? 在改动任何东西之前,添加 characterisation tests,在关键路径上捕获系统当前的行为。即便是高层次的测试,也能给你足够的信心去安全地重构。先建立这份覆盖,是任何遗留项目中最具价值的一步。