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 偏移方法 | 17 | NextPDF v5.1+ 在配接器上公開的 Document 方法,讓混用 API 的程式碼能夠編譯。沒有對應的 TCPDF 6.x 方法。 |
這些數字來自 docs/TCPDF_COVERAGE.md §Summary。此矩陣由 tests/Unit/Compat/Tcpdf/TcpdfApiDriftTest.php 與 tests/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。
1. 鏡像方法 — 相容委派
標題為「1. 鏡像方法 — 相容委派」的區段有九十四個方法直接對應至底層的 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、altimgs | NextPDF 的 image() 接受 file、x、y、width、height。若要建立可點擊的影像,請先繪製影像,再在同一個矩形範圍上加入 Document::link()。不支援影像遮罩與替代影像。 |
writeHTML() | ln、fill、reseth、cell、align | NextPDF 的 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() | spaces | TCPDF 內部的空白追蹤;引擎沒有對應項。 |
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中。
3. 未實作方法 — 空主體
標題為「3. 未實作方法 — 空主體」的區段有四個方法是為了讓舊版原始碼得以編譯而存在,但其主體不做任何事。嚴格模式開啟時,其中三個會擲出 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/。
4. 不適用方法
標題為「4. 不適用方法」的區段有七個 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 中。
5. 現代 API 偏移方法
標題為「5. 現代 API 偏移方法」的區段有十七個來自 NextPDF 核心 v5.1+ 的方法在配接器上公開(trait AdaptsDriftV51),讓混用 TCPDF API 與現代 API 的程式碼仍能編譯。這些方法沒有對應的 TCPDF 6.x 方法。範例:getWarnings()、hasWarnings()、embedFileFromString()、enableBiDi()、beginTag() / endTag()、enableLinearization()、useAesGcm()、useDocumentMac()、setConformanceMode()。請將這些視為現代 API,而非 TCPDF 相容性契約的一部分。
6. 棄用與替代指引
標題為「6. 棄用與替代指引」的區段| 如果你的程式碼呼叫了… | 狀態 | 改為這樣做 |
|---|---|---|
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() | 未實作 / 無作用 | 移除。 |
7. 安全遷移步驟
標題為「7. 安全遷移步驟」的區段- 安裝套件,並在不變更程式碼的情況下,用你既有的測試套件對配接器執行測試 — 請參閱 /integrations/tcpdf-compat/install/ 與 /integrations/tcpdf-compat/quickstart/.
- 在專屬的稽核執行程序(非正式環境)中啟用嚴格模式:
$pdf->setStrictMode(true);。收集每一個TcpdfNotImplementedException。每一個都會指出被忽略參數的確切清單,並提供一則遷移提示。 - 針對每一個擲出位置,選擇:捨棄被忽略的參數,或透過
$pdf->getDocument()將該呼叫遷移至現代 API。 - 對任何針對確切 PDF 位元組進行斷言的測試重新建立基準;改為針對算繪內容或結構屬性斷言。
- 關閉嚴格模式,並部署已稽核的程式碼路徑。保留定期執行的嚴格模式 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)公開