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 时通常会遇到这些问题:
- 改动点多:一个中型项目里,隐式 nullable 参数可能有几十上百处
- 规则容易记错:比如
PHP_ROUND_HALF_UP该换成哪个枚举成员,记错就是 bug - 改完难复核:人工 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_key、array_any、array_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', ], ]);这一步的目的是「目录级 + 规则级」双层排除:整目录不想动就排目录;只有个别文件有风险就按规则精确排除。
收尾:验证结果并接入日常流程
转换完成后做三件事:
- 跑一遍单元测试,确认行为无回归
- 用 PHP 8.4 环境启动项目,确认控制台不再出现相关
E_DEPRECATED - 检查
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),仅供参考