Rector 快速升级 PHP 8.4:一条 withPhpSets() 完成自动化改造
2026/9/16 20:44:04 网站建设 项目流程

Rector 快速升级 PHP 8.4:一条 withPhpSets() 完成自动化改造

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

Rector(PHP 领域里的自动化重构工具)能在不改业务逻辑的前提下批量改写代码。本文带你用 Rector 完成 PHP 8.4 适配:只需在配置里写一行withPhpSets(php84: true),Rector 就会把隐式可空参数、round()取整常量、foreach查找这类老写法,一次性改写成 8.4 推荐的形式,并支持先 dry-run 预览再真正落盘。

Rector 如何知道要升级到 8.4

Rector 的升级能力不是靠正则匹配,而是先把 PHP 文件解析成语法树(AST,即把代码拆成"参数""函数调用""类"这些带类型的节点),再让一条条"规则"(Rector)逐个检查节点:命中就生成新节点,最后重新打印成代码。

它把不同 PHP 版本要改的写法整理成了"规则集"(Set)。其中 PHP 8.4 对应的集是 config/set/php84.php,目前包含 8 条规则:

  • ExplicitNullableParamTypeRector:参数类型补全(见下一节)
  • RoundingModeEnumRectorround()的取整常量改枚举
  • AddEscapeArgumentRector:CSV 函数补escape参数
  • NewMethodCallWithoutParenthesesRector(new Foo())->bar()去掉多余括号
  • ForeachToArrayFind/FindKey/All/AnyRectorforeach循环改array_find/array_all/array_any

每条规则都实现了provideMinPhpVersion(),Rector 会据此决定"当前目标版本下该不该出手",所以不会把 8.4 的语法塞给还在 8.1 的项目里。

三步完成基础配置:withPaths 加 withPhpSets

在目标项目里以开发依赖安装:

composer require rector/rector --dev

composer.json声明了bin/rector可执行入口,安装后即可用vendor/bin/rector调用。

接着在项目根目录建rector.php。它长什么样,仓库自带模板 templates/rector.php.dist 给了答案,在此基础上加一行withPhpSets()即可:

<?php use Rector\Config\RectorConfig; return RectorConfig::configure() ->withPaths([ __DIR__ . '/src', // 告诉 Rector 只动这些目录 ]) ->withPhpSets(php84: true); // 启用 PHP 5.3 → 8.4 的全部升级规则

三个关键点:

  • withPaths()是白名单,没写进路径的文件一律不碰;
  • withPhpSets()只应调用一次,php84: true表示"升级到 8.4",它会自动把 5.3 到 8.3 的历史规则一并打开(withPhpSets的签名在 src/Configuration/RectorConfigBuilder.php);
  • 如果你的composer.json已声明"php": "8.4",可以直接不传参写->withPhpSets(),Rector 会自己读出来,升级目标始终跟着项目走。

它到底会改出什么效果

规则的实际输入输出,都写在每个 Rector 类的getRuleDefinition()里,前后对照最直观。

参数类型补全(rules/Php84/Rector/Param/ExplicitNullableParamTypeRector.php)——8.4 起隐式可空写法被弃用:

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

round()取整常量改枚举(rules/Php84/Rector/FuncCall/RoundingModeEnumRector.php):

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

CSV 函数补escape参数(rules/Php84/Rector/FuncCall/AddEscapeArgumentRector.php):

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

foreach改数组函数(rules/Php84/Rector/Foreach_/ForeachToArrayFindRector.php)——"找到就 break"的循环,正是array_find的语义:

- $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'));

注意:array_find/array_all/array_any是 8.4 才有的函数,规则实现了RelatedPolyfillInterface接口——如果你的运行时还停在 8.3 以下,Rector 会提示你同时装 polyfill 包再启用这几条,避免改出运行不了的新代码。

先 dry-run 预览,再真正落盘

默认命令是process(见 src/Console/Command/ProcessCommand.php),所以可以直接跑vendor/bin/rector,但稳妥做法是先预览:

vendor/bin/rector process --dry-run

--dry-run只打印 diff、不写回文件,你可以逐条确认每处改动。没问题后去掉参数执行,Rector 会输出类似35 files would have changed的汇总,真正的改写发生在这一轮。

如何验证转换结果

三个内置命令可以交叉验证:

# 配置本身有没有写错(拼写、重复调用 withPhpSets 等) vendor/bin/rector validate-config # 看当前配置实际启用了哪些规则,核对是否都是 PHP 8.4 预期内的 vendor/bin/rector list-rules

list-rules的输出应当包含上面 8 条 Php84 规则,且没有混入 8.5+ 的语法改写——这就说明版本目标没写偏。

再落两个"护栏",避免升级跑偏:

  1. 跑完用git diff扫一眼全部改动,确认只动了类型、函数调用这些"表面"结构,业务逻辑没变;
  2. 把 Rector 接进 CI,让每次合并前都检查一次。仓库提供了vendor/bin/rector setup-ci生成平台检查配置,模板在 templates/rector-github-action-check.yaml,改一下触发路径即可。

跑通这轮升级后,你手里其实拿到的是一个可复用的"版本流水线":下一次升到 8.5,只要把php84: true换成php85: true,同样的 dry-run、验证、合入流程再走一遍即可。

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

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

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

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

立即咨询