Rector 如何帮你 3 步完成 PHP 8.4 自动重构:从安装到验证的完整指南
2026/9/16 16:29:51 网站建设 项目流程

Rector 如何帮你 3 步完成 PHP 8.4 自动重构:从安装到验证的完整指南

【免费下载链接】rectorInstant Upgrades and Automated Refactoring of any PHP 5.3+ code项目地址: https://gitcode.com/GitHub_Trending/re/rector

这篇文章带你用 Rector 完成一次真实的 PHP 8.4 升级。Rector 是一个 PHP 自动重构工具,它基于 AST 分析代码,能把隐式 nullable 参数、round() 取整常量、foreach 查找等写法批量改成新特性写法。读完这篇,你会掌握它的安装、配置、dry-run 预览到正式应用的全流程,并看清每条规则实际改了什么。

为什么手动升级到 PHP 8.4 容易翻车

如果你的项目还在 PHP 8.3 及以下,升到 8.4 时通常会遇到这些问题:

  1. 改动点多:一个中型项目里,隐式 nullable 参数可能有几十上百处
  2. 规则容易记错:比如PHP_ROUND_HALF_UP该换成哪个枚举成员,记错就是 bug
  3. 改完难复核:人工 diff 一遍代码,既慢又容易漏

Rector 的思路是把每个新特性写成独立规则,逐条扫描 AST 后做精准替换。规则都放在 rules/Php84/ 目录下,PHP 8.4 规则集的组装逻辑在 config/set/php84.php,改了什么、为什么改,打开源码就能对账。

5 分钟装好 Rector 并生成配置

用 Composer 一键安装

在项目根目录执行:

composer require rector/rector --dev

装完后可执行文件在vendor/bin/rector

写一份最小可用的 rector.php

在项目根目录创建rector.php(也可以用rector init生成骨架):

<?php use Rector\Config\RectorConfig; return RectorConfig::configure() ->withPaths([ __DIR__ . '/src', ]) ->withPhpSets(php84: true);

这里注意两点:withPaths只写你真正要改的目录,避免误伤 vendor;withPhpSets(php84: true)是累计启用到 PHP 8.4 的规则,即 8.0 到 8.4 的规则都会生效,不需要逐版打开。该 API 定义在 src/Configuration/RectorConfigBuilder.php。

先 dry-run 预览,再正式应用转换

用 dry-run 模式检查改动范围

正式动代码前,先跑预览:

vendor/bin/rector process --dry-run

这一步只输出「将会被修改的文件和差异」,不会写回磁盘。你扫一眼输出,确认改动都符合预期再往下走。

确认无误后执行正式转换

vendor/bin/rector process

这一步会把预览中的改动真正写入文件。建议跑完后把 git diff 再过一遍,重点看类型声明相关的改动。

Rector 对 PHP 8.4 代码的具体改法

下面每个例子都来自对应规则源码里的真实用例,你可以直接对照自己项目的效果。

隐式 nullable 参数改为显式写法

ExplicitNullableParamTypeRector 处理 PHP 8.4 开始废弃的隐式 nullable 参数:

- function foo(string $param = null) {} + function foo(?string $param = null) {}

因为 8.4 起这种写法会触发E_DEPRECATED,补上?是必须动作。

round() 取整常量替换为 RoundingMode 枚举

RoundingModeEnumRector 把旧的PHP_ROUND_*常量换成新的RoundingMode枚举:

- round(1.5, 0, PHP_ROUND_HALF_UP); + round(1.5, 0, RoundingMode::HalfAwayFromZero);

新枚举在语义上更清晰,也避免以后常量再次废弃。

去掉 new 表达式外层多余的括号

NewMethodCallWithoutParenthesesRector 利用 PHP 8.4 起(new Foo())->bar()中的括号变为可选:

- (new Request())->withMethod('GET')->withUri('/hello-world'); + new Request()->withMethod('GET')->withUri('/hello-world');

纯风格优化,去掉后调用链更干净,行为完全不变。

foreach 查找循环改写为 array_find()

ForeachToArrayFindRector 识别「赋值 + break」的经典查找循环:

- $found = null; - foreach ($animals as $animal) { - if (str_starts_with($animal, 'c')) { - $found = $animal; - break; - } - } + $found = array_find($animals, fn($animal) => str_starts_with($animal, 'c'));

用 PHP 8.4 新增的array_find()替代 6 行循环,意图一目了然。同族还有array_find_keyarray_anyarray_all对应规则,都在 rules/Php84/Rector/Foreach_/ 目录。

CSV 函数补上 escape 参数

AddEscapeArgumentRector 会提醒并补全 CSV 函数缺少的escape参数:

- str_getcsv($string, separator: ',', enclosure: '"'); + str_getcsv($string, separator: ',', enclosure: '"', escape: '\\');

因为 8.4 起不显式传escape会收到弃用警告,补上默认值即可消除。

另外说明一点:如果你还想给重写方法批量加#[\Override]属性,该特性属于 PHP 8.3,对应规则 AddOverrideAttributeToOverriddenMethodsRector 位于 rules/Php83/。由于withPhpSets(php84: true)是累计启用,它会一并生效,不需要单独配置。

进阶:用 withSkip 收窄规则生效范围

有些遗留代码不想让某条规则碰。在rector.php里加withSkip

return RectorConfig::configure() ->withPaths([ __DIR__ . '/src', ]) ->withPhpSets(php84: true) ->withSkip([ // 排除某个目录 __DIR__ . '/src/Legacy', // 某条规则只跳过个别文件 \Rector\Php84\Rector\Foreach_\ForeachToArrayFindRector::class => [ __DIR__ . '/src/Old/SearchService.php', ], ]);

这一步的目的是「目录级 + 规则级」双层排除:整目录不想动就排目录;只有个别文件有风险就按规则精确排除。

收尾:验证结果并接入日常流程

转换完成后做三件事:

  1. 跑一遍单元测试,确认行为无回归
  2. 用 PHP 8.4 环境启动项目,确认控制台不再出现相关E_DEPRECATED
  3. 检查git diff,逐条确认改动都能对上本文列出的规则

后续建议:

  • vendor/bin/rector process --dry-run加进 CI,一旦有新增代码偏离新风格立刻报警
  • 升级 Rector 版本后重新跑一遍 dry-run,跟进后续 PHP 版本的适配规则
  • 有项目特有的转换需求时,参考 README.md 中的自定义规则说明扩展自己的 Rector

一句话收束:把重复的语法迁移交给 Rector,你只需要审阅 diff,升级 PHP 版本就不再是体力活。

【免费下载链接】rectorInstant Upgrades and Automated Refactoring of any PHP 5.3+ code项目地址: https://gitcode.com/GitHub_Trending/re/rector

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询