跳轉到

PHP 相容性說明

NextPDF 核心以 PHP 8.5 為主要開發目標,充分利用其最新語言特性以實現最高程式碼品質。 對於無法立即升級 PHP 版本的使用者,nextpdf/backport 提供完整的 PHP 8.1 與 7.4 支援。


PHP 版本支援概覽

PHP 版本 支援狀態 套件 備註
8.5 主要支援 nextpdf/core(及所有延伸套件) 完整功能,最新語言特性
8.4 不支援 需要 8.5 特有語法
8.3 不支援 需要 8.5 特有語法
8.1 透過 Backport nextpdf/backport Rector 自動降版,功能完整
7.4 透過 Backport nextpdf/backport Rector 自動降版,功能完整
7.3 以下 不支援 無降版計畫

重要:NextPDF 的版本跳躍設計是刻意的。PHP 8.5 引入的語言特性 (public private(set) 屬性、clone with#[\Override] 等) 對 NextPDF 的架構至關重要,無法透過語法轉換以外的方式提供相同保證。


PHP 8.5 語法特性使用

NextPDF Core 廣泛使用 PHP 8.5 引入的特性。以下是主要用例:

public private(set) — 非對稱可見性屬性

用於 RenderingContext,允許外部讀取但限制修改:

<?php

declare(strict_types=1);

namespace NextPDF\Core;

/**
 * Per-document mutable rendering state.
 * External code may read all properties; only the Document class may write.
 */
final class RenderingContext
{
    public private(set) int    $currentPage  = 0;
    public private(set) float  $cursorX      = 0.0;
    public private(set) float  $cursorY      = 0.0;
    public private(set) string $currentFont  = 'NotoSans';
    public private(set) float  $currentSize  = 12.0;
}

Backport 降版方式:轉換為 private 屬性 + public getter 方法。

clone with — 不可變物件部分複製

用於 Value Object 的不可變更新:

<?php

declare(strict_types=1);

namespace NextPDF\Core\ValueObjects;

final readonly class PageConfig
{
    public function __construct(
        public float  $width,
        public float  $height,
        public float  $marginTop    = 20.0,
        public float  $marginBottom = 20.0,
        public float  $marginLeft   = 15.0,
        public float  $marginRight  = 15.0,
    ) {}

    public function withMargins(
        float $top,
        float $right,
        float $bottom,
        float $left,
    ): self {
        // PHP 8.5 clone with 語法
        return clone($this) with {
            marginTop:    $top,
            marginRight:  $right,
            marginBottom: $bottom,
            marginLeft:   $left,
        };
    }
}

Backport 降版方式:轉換為 new static(...) 帶全部參數的手動複製。

命名引數與建構子屬性提升(PHP 8.0+)

這些特性在 PHP 8.0+ 已支援,Backport 的 PHP 7.4 降版會自動處理:

// PHP 8.x 命名引數
$doc->text(text: 'Hello', x: 20, y: 30);

// PHP 7.4 降版後
$doc->text('Hello', 20, 30);

Backport 套件:nextpdf/backport

nextpdf/backport 是一個 自動生成 的套件。其原始碼由 Rector 從 nextpdf/core 的 PHP 8.5 原始碼自動轉換而來,透過 GitHub Actions 在每次 Core 發版時同步更新。

雙分支模型

Backport 套件使用兩個並行的永久分支,對應不同的 PHP 目標版本:

nextpdf-backport GitHub Repository
├── PHP74  (預設分支)  ←── 目標 PHP 7.4,由 Rector Rules: PHP74 套件處理
└── PHP81              ←── 目標 PHP 8.1,由 Rector Rules: PHP81 套件處理

分支保護PHP74PHP81 均為受保護分支,所有修改必須透過 PR。 任何對 Backport 的更改 必須 同時套用至兩個分支(各自獨立 PR)。

安裝方式

# PHP 8.1 環境
composer require nextpdf/backport:^2.0-php81

# PHP 7.4 環境
composer require nextpdf/backport:^2.0-php74

注意nextpdf/backportnextpdf/core 不可同時安裝。 Backport 套件完全替代 Core,提供相同的 API 介面。


Rector 降版規則說明

Backport 的自動化降版由兩套 Rector 規則集驅動:

PHP74 降版規則集

來源語法(PHP 8.5) 目標語法(PHP 7.4) 說明
public private(set) T $prop private T $prop + public getter 非對稱可見性
clone($obj) with { ... } new static(...) 手動複製 不可變克隆
enum Foo final class Foo + 常數 枚舉類型
readonly class class + readonly 屬性 唯讀類別
fibers 移除 / polyfill 協程(部分功能受限)
match switch/陣列對應 Match 表達式
Named arguments 位置引數 命名引數呼叫
array_is_list() 手動實作 陣列函數
Union types A\|B @param A\|B PHPDoc 聯合型別

PHP81 降版規則集

PHP 8.1 目標較為寬鬆,主要降版項目:

來源語法(PHP 8.5) 目標語法(PHP 8.1) 說明
public private(set) T $prop private T $prop + public getter 非對稱可見性
clone($obj) with { ... } new static(...) 不可變克隆
PHP 8.5 新增函數 polyfill 或等效實作 標準函式庫

API 相容性保證

雖然底層語法不同,但 Backport 套件 保證 以下 API 相容性:

  • 所有 public 方法簽章完全相同
  • 所有 interface 合約完全相同
  • 所有例外類別與訊息完全相同
  • 所有 Composer provides 宣告相同(nextpdf/core-contracts

不保證相同的項目: - 內部實作細節(private / protected 成員) - 效能特性(Backport 版本因語法轉換可能略慢) - PHP 8.5 反射 API 的行為(屬性非對稱可見性反射)


決策矩陣:選擇 PHP 版本

情境 建議
新專案,控制部署環境 使用 PHP 8.5 + nextpdf/core
現有 Laravel 11/12 專案,PHP 8.2-8.4 升級至 PHP 8.5(官方 Laravel 12 支援 PHP 8.2+,但 NextPDF 需要 8.5)
現有 Symfony 7.x 專案,PHP 8.1 使用 nextpdf/backport PHP81 分支
遺留系統,PHP 7.4,無法升級 使用 nextpdf/backport PHP74 分支
共享主機,無法控制 PHP 版本 確認版本 ≥ 8.5 或使用 Backport
需要 Pro / Enterprise 功能 必須使用 PHP 8.5 + nextpdf/core(商業套件不提供 Backport 版本)

商業套件限制nextpdf/pronextpdf/enterprise 僅支援 PHP 8.5, 不提供 Backport 降版版本。若需要商業功能,PHP 8.5 是硬性要求。


從 Backport 遷移至 Core

當你的環境升級至 PHP 8.5 時,遷移步驟非常直接:

# 1. 移除 Backport,安裝 Core
composer remove nextpdf/backport
composer require nextpdf/core

# 2. 確認無破壞性改動
composer test

# 3. 靜態分析(PHPStan Level 10)
composer phpstan

由於 API 介面完全相同,通常不需要修改任何應用程式程式碼


CI/CD 設定(多 PHP 版本矩陣)

若你的 CI 需要測試多個 PHP 版本:

# .github/workflows/ci.yml

jobs:
  test:
    strategy:
      matrix:
        include:
          - php: '8.5'
            package: 'nextpdf/core'
          - php: '8.1'
            package: 'nextpdf/backport:^2.0-php81'
          - php: '7.4'
            package: 'nextpdf/backport:^2.0-php74'

    steps:
      - uses: actions/checkout@v4

      - name: Setup PHP ${{ matrix.php }}
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}
          extensions: mbstring, openssl, fileinfo, gd

      - name: Install dependencies
        run: |
          composer require ${{ matrix.package }} --no-interaction
          composer install --no-interaction

      - name: Run tests
        run: composer test

下一步