跳到內容

NextPDF compat-legacy 的 TCPDF 方法涵蓋範圍

nextpdf/compat-legacy 是一個相容層,不是 TCPDF 的分支,也不是承諾行為完全一致的複製品。它在 NextPDF 核心引擎之上,公開 TCPDF 6.x 的公開方法名稱、參數順序與預設值。大多數呼叫會直接對應到一項 NextPDF Document 操作。少數已界定的方法則會接受 NextPDF 不採納的舊版參數,或完全不產生作用。

本頁是逐方法稽核的讀者導向摘要。權威且經測試驗證的涵蓋範圍矩陣位於儲存庫中的 docs/TCPDF_COVERAGE.md。當本頁與儲存庫內矩陣不一致時,以儲存庫內矩陣為準,因為測試套件會對它做出斷言。

在遷移之前,請用本頁回答一個問題:對我的程式碼基底呼叫到的每一個 TCPDF 方法,配接器實際上會做什麼?

本次稽核審視了約 120 個 TCPDF 6.x 公開方法。每一個 TCPDF 方法都歸入四個類別之一。

類別數量對你的意義
鏡像 — 完全委派94此呼叫直接對應到一項 NextPDF Document 方法。就所記載的參數而言,行為相容。
靜默忽略 — 部分15此方法會執行並產生輸出,但有一個或多個 TCPDF 參數不會有任何作用。這是已記載的行為差異。
未實作 — 空主體4此方法為了原始碼相容性而存在,但不做任何事。
不適用7此 TCPDF 方法對 PDF 輸出沒有任何作用;刻意排除。
新增的現代 API 偏移方法17NextPDF v5.1+ 在配接器上公開的 Document 方法,讓混用 API 的程式碼能夠編譯。沒有對應的 TCPDF 6.x 方法。

這些數字來自 docs/TCPDF_COVERAGE.md §Summary。此矩陣由 tests/Unit/Compat/Tcpdf/TcpdfApiDriftTest.phptests/Unit/Compat/Tcpdf/TcpdfStrictModeTest.php 加以驗證。

用語說明。 本套件並不宣稱自己是「直接替換」 (drop-in replacement),也不宣稱「100% 與 TCPDF 相容」。它透過直接委派涵蓋所審視約 120 個 TCPDF 方法中的 94 個;其餘方法則有下文所述、已記載的行為差異。較準確的說法是「與 TCPDF 相容的替代方案」,且具備「已知並經測試的相容介面」。

配接器由 25 個單一職責的 concern trait(src/Compat/Tcpdf/Concerns/)構成,共公開 273 個方法;另有少數生命週期與逃生口(escape-hatch)方法位於 TCPDF 類別本身。上述涵蓋範圍類別計算的是不重複的 TCPDF 6.x API 介面方法(約 120 個),不是配接器的公開方法總數。這兩個數字衡量的是不同面向:API 介面涵蓋範圍與實作規模。若你在套件 README.md 中看到較少的 trait 數量或方法數量,請以 docs/TCPDF_COVERAGE.md 與本頁為準 — README 摘要早於 AdaptsDriftV51 trait。

有九十四個方法直接對應至底層的 NextPDF\Core\Document 實例。在引擎使用 camelCase 的地方,PascalCase 的 TCPDF 名稱會對應到 camelCase 的 NextPDF 名稱;配接器也同時接受兩種拼寫,兼顧向前與向後相容性。

代表性群組(完整表格:docs/TCPDF_COVERAGE.md §1):

TCPDF 領域範例方法配接器 trait
生命週期Output(), Close(), getPDFData()AdaptsLifecycle
頁面AddPage(), getNumPages(), deletePage()AdaptsPageManagement
文字Cell(), MultiCell(), Write(), Text(), Ln()AdaptsTextOutput
字型SetFont(), SetFontSize(), AddFont()AdaptsFonts
色彩SetTextColor(), SetDrawColor(), SetFillColor()AdaptsColors
繪圖Line(), Rect(), Circle(), Polygon(), Arrow()AdaptsDrawing
變換Rotate(), Scale(), Translate(), Skew(), Mirror*()AdaptsTransforms
導覽AddLink(), Annotation(), addTOC()AdaptsNavigation

對這些方法,依 NextPDF 記載的參數來看,觀察到的行為與 TCPDF 6.x 相容。配接器並不斷言會產生位元組完全相同的 PDF 輸出。底層引擎是一套獨立的 PDF 2.0 實作,因此即使可見結果相同,算繪後的位元組仍會不同。若你的測試是針對確切的 PDF 位元組進行斷言,而不是針對算繪內容,請預期這些斷言需要重新建立基準。建議的重新建立基準策略,請參閱 /integrations/tcpdf-compat/migration/。

2. 靜默忽略方法 — 已記載的行為差異

標題為「2. 靜默忽略方法 — 已記載的行為差異」的區段

這 15 個方法會執行並產生輸出,但至少有一個 TCPDF 參數只是為了原始碼相容性而被接受,之後會遭忽略。這是遷移前最重要、必讀的一節,因為呼叫不會失敗 — 它只是靜默地少做了 TCPDF 原版會做的事。

TCPDF 方法被忽略的參數相容的替代方案
Image()type、link、align、resize、dpi、palign、ismask、imgmask、border、fitbox、hidden、fitonpage、alt、altimgsNextPDF 的 image() 接受 file、x、y、width、height。若要建立可點擊的影像,請先繪製影像,再在同一個矩形範圍上加入 Document::link()。不支援影像遮罩與替代影像。
writeHTML()ln、fill、reseth、cell、alignNextPDF 的 writeHtml() 僅處理內容。若需版面控制,請透過現代 API 將 HTML 包在帶定位的區塊中。
writeHTMLCell()border(字串形式)、ln、fill、reseth、autopadding寬度、高度、位置與布林值 border 會被採納;較完整的儲存格版面設定沒有對應項。
ImageEps()link、useBoundingBox、align、palign、border、fitonpage、fixoutvals僅限位置與大小。
ImageSVG()link、align、palign、border、fitonpage僅限位置與大小。
SetProtection()mode(非零)、pubkeys(非空)NextPDF 對標準處理器一律使用 AES-256。若需以憑證為基礎的加密,請使用配接器公開的現代 setPublicKeyEncryption()(請參閱 /integrations/tcpdf-compat/security-and-operations/)。
Bookmark()style、color、x、isNamedDest標題、層級與 y 座標會被採納。
setDestination()page、x名稱與 y 座標會被採納。
Link()spacesTCPDF 內部的空白追蹤;引擎沒有對應項。
Annotation()Subtype 以外的 option 鍵、spaces類型、位置與文字會被採納。
SetLineStyle()width 以外的虛線樣式(dash-pattern)細節核心線條屬性會被對應。
setAlpha()部分混合模式(blend-mode)對應部分混合模式名稱沒有引擎對應項。
Polycurve()完整參數清單在預設模式下為無作用(no-op);引擎沒有對應項。
PieSectorXY()完整參數清單只會部分對應(中心到外緣的線條有所不同)。
RoundedRectXY()各角獨立的圓角半徑僅限統一的圓角半徑。

配接器如何處理這些差異,取決於嚴格模式(strict mode)(請參閱 /integrations/tcpdf-compat/configuration/)。嚴格模式關閉時(也就是向後相容的預設值),這些呼叫會靜默降級。嚴格模式開啟時,每一個忽略參數的呼叫都會擲出 TcpdfNotImplementedException,並附帶被忽略參數的確切清單與一則遷移提示。嚴格模式是一項稽核工具,不是正式環境設定。

嚴格模式的設計遵循一項原則:呼叫端必須能察覺自己的意圖何時未被採納。OWASP ASVS 5.0 §16.5.3 指出,應用程式應以優雅且安全的方式失敗,並防止 fail-open 情況。靜默遺失參數是一種開發體驗陷阱,而非漏洞;但同樣的明確失敗(fail-explicitly)原則仍然適用。所釘選的條款摘要位於頁面前置資料的 citations 中。

有四個方法是為了讓舊版原始碼得以編譯而存在,但其主體不做任何事。嚴格模式開啟時,其中三個會擲出 TcpdfNotImplementedException。第四個(Open())是刻意設計的安全無作用方法,永遠不會擲出例外,因為從舊版程式碼中移除它一律是安全的。

TCPDF 方法行為替代方案
setSignature()無作用(不儲存任何可操作內容)。嚴格模式下會擲出例外。數位簽署需要商用版 NextPDF。請搭配 CertificateInfo 值物件使用現代簽章 API — 請參閱 /integrations/tcpdf-compat/security-and-operations/.
addEmptySignatureAppearance()無作用。嚴格模式下會擲出例外。setSignature() 相同的商用版限制。
endPage()無作用。嚴格模式下會擲出例外。NextPDF 會自動管理頁面生命週期。請移除此呼叫。
Open()安全的無作用。永遠不會擲出例外。NextPDF 會自動開啟文件。移除此呼叫一律是安全的。

透過此配接器,核心引擎並不提供簽署功能。配接器公開了一個會委派給引擎的現代簽章進入點;基礎簽章支援則受限於商用版。本文件不對任何版本的長期驗證(long-term-validation)或加蓋時戳的簽章設定檔做出任何宣稱 — 確切且保守的說明請參閱 /integrations/tcpdf-compat/security-and-operations/。

有七個 TCPDF 方法對 PDF 輸出沒有任何作用,已刻意排除。呼叫它們是無害的。

TCPDF 方法排除原因
setDocCreationTimestamp() / setDocModificationTimestamp()狀態會保存在配接器上,但未接通至文件的 XMP 中繼資料。在輸出中不可見。
setSRGBmode()NextPDF 的色彩管理與此旗標無關。
setPDFVersion()NextPDF 會依其 conformance/output 設定檔選擇 PDF 版本;沒有直接的設定方法(setter)。配接器會發出一則通知並繼續執行。
setDocInfoUnicode()NextPDF 一律使用 Unicode;依設計此旗標無作用。
setDefaultMonospacedFont()引擎沒有對應項;改以 HTML/CSS 樣式套用。
setFontSubsetting()NextPDF 一律會對內嵌字型進行子集化(subset);此旗標實際上永遠開啟。

PDF 版本由引擎固定決定。輸出會以 PDF 2.0(ISO 32000-2)寫出。ISO 32000-2 §7.5.2 規定,符合規範的寫入端應將文件版本 — 於檔案標頭或目錄的 Version 項中 — 標示為 2.0。它也規定,儲存時不得將檔案版本降至較舊的版本。這與配接器的行為一致:諸如 setPDFVersion('1.4') 之類的呼叫,無法透過此配接器將輸出降版至較舊的 PDF 版本。所釘選的條款摘要位於頁面前置資料的 citations 中。

有十七個來自 NextPDF 核心 v5.1+ 的方法在配接器上公開(trait AdaptsDriftV51),讓混用 TCPDF API 與現代 API 的程式碼仍能編譯。這些方法沒有對應的 TCPDF 6.x 方法。範例:getWarnings()hasWarnings()embedFileFromString()enableBiDi()beginTag() / endTag()enableLinearization()useAesGcm()useDocumentMac()setConformanceMode()。請將這些視為現代 API,而非 TCPDF 相容性契約的一部分。

如果你的程式碼呼叫了…狀態改為這樣做
Error()行為已變更(已強化)TCPDF 的 die() 已改為擲出 RuntimeException。請以 try/catch 包覆有風險的呼叫;不要仰賴行程終止。
setPDFVersion()不適用移除。輸出一律為 PDF 2.0。
setUserRights()在 PDF 2.0 中已棄用移除。此呼叫會發出一則 E_USER_DEPRECATED 通知並予以忽略。
setSignature()核心中未實作請在商用版上遷移至現代簽章 API。
帶有額外參數的 Image(...)靜默忽略精簡為 file、x、y、w、h;可點擊的影像請加入 Document::link()
endPage() / Open()未實作 / 無作用移除。
  1. 安裝套件,並在不變更程式碼的情況下,用你既有的測試套件對配接器執行測試 — 請參閱 /integrations/tcpdf-compat/install/ 與 /integrations/tcpdf-compat/quickstart/.
  2. 在專屬的稽核執行程序(非正式環境)中啟用嚴格模式:$pdf->setStrictMode(true);。收集每一個 TcpdfNotImplementedException。每一個都會指出被忽略參數的確切清單,並提供一則遷移提示。
  3. 針對每一個擲出位置,選擇:捨棄被忽略的參數,或透過 $pdf->getDocument() 將該呼叫遷移至現代 API。
  4. 對任何針對確切 PDF 位元組進行斷言的測試重新建立基準;改為針對算繪內容或結構屬性斷言。
  5. 關閉嚴格模式,並部署已稽核的程式碼路徑。保留定期執行的嚴格模式 CI 作業,以便在你重構時攔截退化。

包含程式碼的完整流程:/integrations/tcpdf-compat/migration/.

  • docs/TCPDF_COVERAGE.md — 具權威性、經測試驗證的涵蓋範圍矩陣(儲存庫內)
  • /integrations/tcpdf-compat/migration/ — 端對端的 TCPDF 至 NextPDF 遷移策略
  • /integrations/tcpdf-compat/configuration/ — 嚴格模式與配接器設定
  • /integrations/tcpdf-compat/security-and-operations/ — 加密與簽章態勢
  • /integrations/tcpdf-compat/integration/ — 將配接器整合至應用程式
  • /integrations/tcpdf-compat/boot-and-discovery/ — 類別別名註冊與門面(facade)公開