跳到內容

設定 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 常數轉換為靜態屬性。早期執行環境會以「Traits cannot have constants」拒絕 trait 常數。這條規則也會將 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/ — 每個失敗階段代表的意義。