從 TCPDF 6.x 遷移至 NextPDF
快速概覽
標題為「快速概覽」的區段這項遷移遵循明確順序:先以最小幅度變更切換到 NextPDF 引擎;驗證已可運作的部分;稽核尚未運作的部分;逐一修正呼叫點;接著移除轉接層。相容性層支援第二到第四步,但它不是最終目的地。
本頁說明遷移策略。若要了解任一方法的確切行為,請搭配使用 /integrations/tcpdf-compat/method-coverage/ 與儲存庫內的權威對照表 docs/TCPDF_COVERAGE.md。
遷移模型
標題為「遷移模型」的區段每個階段都會讓應用程式維持在可交付狀態。你永遠不需要一次完成整體切換。
階段 1 — 替換相依套件
標題為「階段 1 — 替換相依套件」的區段安裝 nextpdf/compat-legacy(請參閱 /integrations/tcpdf-compat/install/)。請勿立即移除 tecnickcom/tcpdf——同時保留兩者可讓你進行比對。
選擇舊版呼叫點要如何解析該類別:
- **建議做法:**逐檔將
use/require改為use NextPDF\Compat\Tcpdf\TCPDF;。這種做法明確,也可用 grep 搜尋。 - **當你尚無法變更呼叫點時:**在啟動時以
LegacyBootstrap::enableAliases()一次性啟用選用的全域別名(請參閱 /integrations/tcpdf-compat/boot-and-discovery/)。這會將\TCPDF以及四個輔助類別解析至轉接層。
這兩種策略在實務上互斥。如果真正的 TCPDF 函式庫仍可被自動載入,而你又啟用了全域別名, 則當
\TCPDF類別已存在時,別名會被略過。你可能因此在無聲無息間持續使用舊版 TCPDF。在階段 1 期間,建議採用逐檔匯入,這樣你才能明確知道每個呼叫點使用的是哪個類別。請參閱 /integrations/tcpdf-compat/troubleshooting/.
階段 2 — 不變更地執行既有的測試套件
標題為「階段 2 — 不變更地執行既有的測試套件」的區段在不做其他程式碼變更的情況下,針對轉接層執行完整測試套件。大多數委派方法(受測的約 120 個中有 94 個)行為都相容。請預期會出現兩類可預測的失敗:
- **位元組層級的斷言。**比對確切 PDF 位元組的測試會失敗,因為這個引擎是獨立實作。這是預期行為,並非缺陷。請將這些測試延後至階段 4 處理。
- **回傳值分支。**少數方法回傳的是相容性佔位值,而非計算後的數值;其中最值得注意的是
MultiCell()回傳1,而Write()回傳0。依據這些回傳值進行分支判斷的程式碼需要調整。
為每一項失敗建立記錄。將每一項歸類為 位元組基準、回傳值 或 真正的行為落差。
階段 3 — 嚴格模式稽核
標題為「階段 3 — 嚴格模式稽核」的區段這個階段會讓遷移變得安全可控。啟用嚴格模式後,執行測試套件(或具代表性的正式環境路徑):
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\Exception\TcpdfNotImplementedException;use NextPDF\Compat\Tcpdf\TCPDF;
function renderInvoice(TCPDF $pdf): void{ // ... your existing rendering code, unchanged ...}
$pdf = new TCPDF('P', 'mm', 'A4');$pdf->setStrictMode(true);
try { renderInvoice($pdf); $pdf->Output(__DIR__ . '/audit.pdf', 'F');} catch (TcpdfNotImplementedException $e) { // Each message names the method, the ignored parameters, and a hint. fwrite(STDERR, 'MIGRATION GAP: ' . $e->getMessage() . "\n");}每個 TcpdfNotImplementedException 都是一項工作項目。訊息會包含方法名稱、確切被忽略的參數清單,以及一則遷移提示。會擲出例外的方法集合已列舉於 tests/Unit/Compat/Tcpdf/TcpdfStrictModeTest.php,並有測試斷言涵蓋。每一項的原理說明則記載於 docs/TCPDF_COVERAGE.md。
請將嚴格模式作為專屬的 CI 工作執行,而不要在正式環境中執行。它的目的在於揭露落差,不是讓正式環境擲出例外。
階段 4 — 修正呼叫點
標題為「階段 4 — 修正呼叫點」的區段針對每項落差,選擇成本最低的正確修正方式:
| 落差樣態 | 修正方式 |
|---|---|
被忽略的參數無關緊要(e.g. 你從未依賴的 TCPDF $align) | 移除該參數。該呼叫就會完全相容。 |
被忽略的參數確有影響(e.g. 可點擊的 Image() 連結) | 透過現代化 API 重新表達。先繪製影像,再於該矩形範圍上加入 Document::link()。 |
方法尚未實作(setSignature()、endPage()) | endPage() / Open():移除該呼叫。簽署:請參閱 /integrations/tcpdf-compat/security-and-operations/——需要商用版本。 |
不適用的方法(setPDFVersion()、setUserRights()) | 移除。輸出一律為 PDF 2.0;user-rights 在 PDF 2.0 中已棄用。 |
| 回傳值分支 | 自行計算該數值,或將該邏輯移轉至現代化 API。 |
對於任何 TCPDF 介面無法表達的項目,請使用這個逃生出口:
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\TCPDF;
$pdf = new TCPDF();$pdf->AddPage();
// Legacy path stays as-is for the parts that work:$pdf->SetFont('helvetica', '', 12);$pdf->Cell(0, 10, 'Header line', 0, 1);
// Modern path for what the TCPDF surface cannot express here:$document = $pdf->getDocument();$document->image('logo.png', 10, 30, 40, 0);$document->link(10, 30, 40, 20, 'https://example.com');重新建立位元組層級測試的基準
標題為「重新建立位元組層級測試的基準」的區段用針對真正重要事項的斷言,取代確切位元組的斷言:
- 輸出以
%PDF開頭,且可被解析(冒煙測試層級)。 - 已算繪的文字內容存在(擷取文字並對其斷言)。
- 結構屬性(頁數、頁面大小、是否存在大綱)相符。
這是一次性成本,並能產生足以在未來引擎升級後仍有效的測試。
階段 5 — 移除 TCPDF 相依套件
標題為「階段 5 — 移除 TCPDF 相依套件」的區段一旦嚴格模式稽核通過、正式環境的嚴格模式維持關閉,且測試套件在重新建立基準的斷言下皆為綠燈,即可移除 tecnickcom/tcpdf:
composer remove tecnickcom/tcpdf重新執行測試套件。若仍有任何項目解析至真正的 TCPDF 類別,代表階段 1 的別名注意事項生效了——請修正其餘呼叫點,明確匯入轉接層。
階段 6 — 淘汰轉接層
標題為「階段 6 — 淘汰轉接層」的區段轉接層是遷移輔助工具,不是永久存在的層。在 TCPDF 已移除且引擎已完成驗證後,請漸進式淘汰轉接層:
- 在每個模組中,將
new TCPDF(...)替換為現代化的NextPDF\Core\Document建構方式。 - 將 TCPDF 方法呼叫替換為其現代化的對應項目(你在階段 4 已加入的
getDocument()呼叫就是範本)。 - 當某個模組不再參考轉接層時,刪除其相容性匯入。
- 當沒有任何模組參考轉接層時,將
nextpdf/compat-legacy從composer.json中移除。
此時你便已在現代化的 PDF 2.0 API 之上運行,不再有相容性層。
遷移檢查清單
標題為「遷移檢查清單」的區段- 已安裝
nextpdf/compat-legacy;引擎連結已驗證。 - 呼叫點明確匯入轉接層(或已啟用別名,並已將真正的 TCPDF 從自動載入路徑中移除)。
- 已針對轉接層執行完整測試套件;失敗已分類。
- 已加入嚴格模式 CI 工作;每項落差皆已建立記錄。
- 每項落差皆已修正(移除參數/改用現代化 API/移除呼叫)。
- 位元組層級的斷言已重新建立基準至 content/structure.
- 已移除
tecnickcom/tcpdf;測試套件為綠燈。 - 已逐模組淘汰轉接層;相依套件已移除。
另請參閱
標題為「另請參閱」的區段- /integrations/tcpdf-compat/method-coverage/ — 各方法行為與替換指引
docs/TCPDF_COVERAGE.md— 權威且經測試驗證的對照表- /integrations/tcpdf-compat/configuration/ — 將設定從全域常數中遷出
- /integrations/tcpdf-compat/security-and-operations/ — 遷移期間的加密與簽署
- /integrations/tcpdf-compat/troubleshooting/ — alias/real-TCPDF 衝突與其他陷阱