跳转到内容

配置 NextPDF Backport 构建器

构建工具——并非运行时依赖包。本页说明如何在构建期间配置源代码转换。这些内容都不会随产品交付到下游运行环境。

这项转换由 rector/config/ 下的三个 Rector 配置文件,以及 rector/rules/ 下的三条自定义规则驱动。选用哪个配置取决于目标版本。PHP 8.1 目标只需要单个 Rector 阶段。PHP 7.4 目标则采用两阶段流程,中间包含一个修正阶段。之所以需要第二个阶段,是因为 Rector 无法在单次遍历中解析枚举案例的默认值。

文件用途使用于
rector/config/rector-php81.php单阶段降级至 PHP 8.1PHP 8.1 目标
rector/config/rector-php74-enums.php第 1 阶段——将枚举转换为常量列表类PHP 7.4 目标
rector/config/rector-php74.php第 2 阶段——完整降级至 PHP 7.4PHP 7.4 目标

每个配置都会针对 Rector 原生支持的功能调用其降级规则集链(withDowngradeSets(php81: true)withDowngradeSets(php74: true))。对于 Rector 无法原生处理的功能,则注册自定义规则。已对照 rector/config/ 中的三个文件验证。

rector-php81.phprector-php74.php 都会跳过 */tests/Benchmark/*。这些基准测试脚本引用了 Rector 无法解析的外部 PDF 库,会导致其默认参数解析器崩溃。rector-php74.php 还会额外跳过 DowngradeHashAlgorithmXxHashRector。该内置规则会在已于现代 PHP 中弃用的 MHASH_XXH* 常量上崩溃,而源代码并未使用 xxHash。已对照两个文件中的 withSkip() 调用验证。

此仓库共提供三条自定义 Rector 规则。这三条规则都会注册到 rector-php81.php;其中的非对称可见性、clone-with 与 trait 常量规则也会注册到 rector-php74.php。这一点由 tests/Rector/RectorRulesMetadataTest.php 直接断言:该测试会构造每条规则,并检查其定义与节点类型。

移除非对称可见性的 set 修饰符。声明为 public private(set) 的属性或提升参数会变成普通的 public。读取访问会保留;编译期的 setter 限制会被移除。如果没有任何读取可见性留存,规则会默认使用 public。以下转换有源代码佐证,取自 tests/Rector/Fixtures/DowngradeAsymmetricVisibility/public_private_set.php.inc

before
<?php
class Config {
public private(set) float $x = 0.0;
public private(set) string $name = '';
public private(set) int $count = 0;
}
after
<?php
class Config {
public float $x = 0.0;
public string $name = '';
public int $count = 0;
}

将带有覆盖数组的 clone() 函数形式改写为一次复制,随后进行明确的属性赋值,最后返回临时变量。临时变量计数器会按文件重置。这条规则必须在移除 readonly 属性的规则之后执行,否则展开后的赋值会在 readonly 属性上失败。以下转换有源代码佐证,取自 tests/Rector/Fixtures/DowngradeCloneWith/return_clone_with.php.inc

before
<?php
class PageSize {
public float $width = 0.0;
public float $height = 0.0;
public function withDimensions(float $width, float $height): self {
return clone($this, ['width' => $width, 'height' => $height]);
}
}
after
<?php
class PageSize {
public float $width = 0.0;
public float $height = 0.0;
public function withDimensions(float $width, float $height): self
{
$__cloneResult1 = clone $this;
$__cloneResult1->width = $width;
$__cloneResult1->height = $height;
return $__cloneResult1;
}
}

这条规则有已载明的限制。参数匹配采用非递归模式,因此包含嵌套括号的覆盖值不会被处理。只有字符串类型的数组键会被解析为属性名称。已对照 rector/rules/DowngradeCloneWithRector.php 及其 fixture 测试包验证。

将 trait 常量转换为静态属性。trait 常量在早期运行环境中会因「Traits cannot have constants」而被拒绝。这条规则也会将 self::CONSTstatic::CONST 引用改写为静态属性形式。可见性会保留;final 修饰符会被移除,因为较旧的目标版本不支持 final 属性。带类型的类常量会变成带类型的属性。以下转换有源代码佐证,取自 tests/Rector/Fixtures/DowngradeTraitConstants/private_constant.php.inc

before
<?php
trait HasLimit
{
private const MAX_SIZE = 1024;
public function getLimit(): int
{
return self::MAX_SIZE;
}
}
after
<?php
trait HasLimit
{
private static $MAX_SIZE = 1024;
public function getLimit(): int
{
return self::$MAX_SIZE;
}
}

PHP 7.4 目标无法通过单一阶段完成。Rector 的默认参数值解析器会在构造函数提升中的枚举案例默认值上崩溃。因此,构建脚本会执行:

  1. 第 1 阶段——枚举预处理。 rector-php74-enums.php 只执行内置的枚举转常量列表类规则。这个阶段完成后,枚举案例会变成普通的类常量。
  2. 清除缓存。 清除 Rector 缓存,避免第二个阶段看到过时的语法树。
  3. 后处理修正。 scripts/build.php 会改写枚举转类规则未涵盖的模式。原本的枚举实例方法会变成静态方法。EnumClass::Case->value->name 访问会被解析。Rector 无法绑定的命名参数会被展平为位置参数。这些语法模式如果不处理,就会在 PHP 7.4 上造成解析错误。
  4. 第 2 阶段——完整降级。 rector-php74.php 会执行完整的 PHP 7.4 降级规则链,并附加自定义规则。

已对照 scripts/build.phprunRector()postProcessFixups())验证。

scripts/build.php 是协调器。它的选项已对照 getopt() 调用与 Build 构造函数验证:

标志默认值作用
--version=<x.y.z>2.0.0写入生成的 composer.jsonCHANGELOG.md 版本号
--source-dir=<path>c:/Users/admin/Documents包含同级源代码仓库的根目录
--output-dir=<path><repo>/output所生成分发包的写入位置
--target=php74 | --target=php81php81降级目标。 php74 会强制仅限核心并停用 Pro
--dry-run关闭以只报告模式执行每个阶段;跳过复制与 Rector
--no-pro关闭排除 Pro 包(仅适用于 PHP 8.1 目标;PHP 7.4 已经排除它)

无效的 --target 值会在任何工作开始之前抛出 InvalidArgumentException。已对照 Build::__construct()VALID_TARGETS 防护)验证。

脚本指令用途
composer testphpunit执行规则 fixture 测试包
composer analysephpstan analyse rector/rules scripts --level=10对构建代码进行静态分析
composer buildphp scripts/build.php完整构建
composer build:dryphp scripts/build.php --dry-run试运行构建

已对照 composer.jsonscripts 验证。

  • /integrations/backport/quickstart/ — 执行试运行与完整构建。
  • /integrations/backport/troubleshooting/ — 了解每个失败阶段代表的意义。