콘텐츠로 이동

NextPDF Backport Builder 구성

빌드 도구입니다 — 런타임 의존성이 아닙니다. 이 페이지의 모든 내용은 빌드 타임에 소스를 어떻게 변환할지 구성합니다. 어떤 것도 다운스트림 런타임으로 배포되지 않습니다.

변환은 rector/config/ 아래의 세 개 Rector 구성 파일과 rector/rules/ 아래의 세 개 커스텀 규칙으로 구동됩니다. 대상에 따라 사용할 구성이 달라집니다. PHP 8.1 대상은 단일 Rector 패스입니다. PHP 7.4 대상은 중간에 수정 단계가 있는 2-패스 파이프라인입니다. Rector가 한 번의 순회로 enum case 기본값을 해석할 수 없기 때문에 두 번째 패스가 필요합니다.

파일용도사용처
rector/config/rector-php81.phpPHP 8.1로의 단일 패스 다운그레이드PHP 8.1 대상
rector/config/rector-php74-enums.php패스 1 — enum을 상수 목록 클래스로 변환PHP 7.4 대상
rector/config/rector-php74.php패스 2 — PHP 7.4로의 전체 다운그레이드PHP 7.4 대상

각 구성은 Rector가 기본적으로 처리하는 기능에 대해 Rector의 다운그레이드 세트 체인(withDowngradeSets(php81: true) 또는 withDowngradeSets(php74: true))을 호출합니다. 그런 다음 처리하지 않는 기능에는 커스텀 규칙을 등록합니다. rector/config/ 내의 세 파일을 기준으로 검증되었습니다.

rector-php81.phprector-php74.php는 모두 */tests/Benchmark/*를 건너뜁니다. 벤치마크 스크립트는 Rector가 해석할 수 없는 외부 PDF 라이브러리를 참조하며, 이 때문에 Rector의 기본 매개변수 해석기가 충돌합니다. 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와 해당 픽스처 스위트를 기준으로 검증되었습니다.

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의 기본 매개변수 값 해석기는 생성자 승격에서 enum case 기본값을 만나면 충돌합니다. 따라서 빌드 스크립트는 다음을 실행합니다:

  1. 패스 1 — enum 사전 처리. rector-php74-enums.php는 내장 enum-to-constant-list-class 규칙만 실행합니다. 이 패스가 끝나면 enum case는 일반 클래스 상수가 됩니다.
  2. 캐시 비우기. 두 번째 패스가 오래된 트리를 보지 않도록 Rector 캐시가 비워집니다.
  3. 후처리 수정. scripts/build.php는 enum-to-class 규칙이 다루지 않는 패턴을 다시 작성합니다. 이전 enum 인스턴스 메서드는 정적 메서드가 됩니다. EnumClass::Case->value->name 접근이 해석됩니다. Rector가 바인딩할 수 없었던 명명된 인자는 위치 인자로 평탄화됩니다. 이들은 그대로 두면 PHP 7.4에서 구문 오류가 될 구문 패턴입니다.
  4. 패스 2 — 전체 다운그레이드. rector-php74.php는 전체 PHP 7.4 다운그레이드 체인과 커스텀 규칙을 실행합니다.

scripts/build.php(runRector(), 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규칙 픽스처 스위트 실행
composer analysephpstan analyse rector/rules scripts --level=10빌드 코드를 정적 분석
composer buildphp scripts/build.php전체 빌드
composer build:dryphp scripts/build.php --dry-runDry-run 빌드

composer.jsonscripts를 기준으로 검증되었습니다.

  • /integrations/backport/quickstart/ — dry-run과 전체 빌드를 실행합니다.
  • /integrations/backport/troubleshooting/ — 각 실패 단계의 의미를 설명합니다.