跳到內容
getnextpdf.com

Pro 版本

Merge — 深入參考

本頁是 NextPDF Pro Merge 模組 NextPDF\Pro\Merge 的合約層級參考。SmartMerger 將數份輸入文件組裝為一份,並套用 Pro 增強功能:從各輸入標籤產生的整併書籤樹、整份文件去重、各輸入的頁面範圍選取,以及內部連結偵測。SemanticSplitter 是搭配的結構感知切分進入點。本頁陳述公開 API、可觀察的行為合約、資源界限與失敗模式。任務導向的設定與範例位於 Merge 能力頁面

此能力隨附於 NextPDF Pronextpdf/pro),並以 Pro 階層的授權封套啟用。未持有該權益的部署不會載入此能力的類別。比較版本並取得授權

沒有任何執行階段能力旗標控管此模組。只要安裝並授權 nextpdf/pro,Merge 類別即可使用。

符號參數預設行為回傳拋出或失敗於備註
SmartMerger::__construct()?PdfMerger $coreMerger = null, ?PdfSplitter $splitter = null接受並忽略舊版 core merger;null 的 splitter 會建構預設的 Pro splitter$coreMerger 僅為向後相容的建構而保留
SmartMerger::merge()list<MergeInput> $inputs, SmartMergeConfig $config = new SmartMergeConfig()縮減頁面範圍、對整份輸入去重、委派基礎組裝,接著依設定注入書籤並計數連結SmartMergeResult輸入清單為空時拋出 InvalidArgumentException;輸入數量超過 maxInputs 或某個輸入超過 maxBytesPerInput 時拋出 OverflowException唯一的合併進入點
MergeInput::__construct()string $pdfData, list<PageRange> $pageRanges = [], string $label = ''值物件;$pageRanges 為空會選取所有頁面唯讀
MergeInput::hasPageRanges()當輸入帶有至少一個頁面範圍時為 Truebool
SmartMergeConfig::__construct()bool $consolidateBookmarks = true, bool $deduplicatePages = false, bool $rewriteLinks = true, int $maxInputs = 100, int $maxBytesPerInput = 100_000_000持有增強開關與資源界限的值物件唯讀;去重需明確啟用
SmartMergeConfig::default()書籤與連結掃描開啟、去重關閉self靜態工廠
SmartMergeConfig::basic()所有增強關閉;僅做基礎串接self靜態工廠
SmartMergeResult::__construct()string $pdfData, int $totalPages, int $sourceCount, int $mergedSize, int $bookmarksAdded = 0, int $duplicatesRemoved = 0, int $linksRewritten = 0, list<string> $inputLabels = []承載合併後位元組與整併統計的唯讀載體唯讀
SmartMergeResult::isValid()當輸出以 %PDF 標頭開頭時為 Truebool僅檢查標頭
SmartMergeResult::hasOptimizations()當有任何重複被移除或有任何連結被計數時為 Truebool
SemanticSplitter::__construct()?PdfSplitter $splitter = nullnull 引數會建構預設的 Pro splitter供測試用的建構子注入
SemanticSplitter::splitByStructure()string $pdfData, float $headingFontThreshold = 14.0偵測標題級的 Tf 運算子作為區段起點並於這些邊界切分;未偵測到結構時回傳單一整份文件區段SplitResult緩衝區為空或缺少 %PDF 標頭時拋出 InvalidArgumentException;輸入超過 100 MB 時拋出 OverflowException退回 Core 的頁面範圍切分
public function __construct(
?PdfMerger $coreMerger = null,
?PdfSplitter $splitter = null,
)
public function merge(
array $inputs,
SmartMergeConfig $config = new SmartMergeConfig(),
): SmartMergeResult
public function __construct(
public string $pdfData,
public array $pageRanges = [],
public string $label = '',
)
public function hasPageRanges(): bool
public function __construct(
public bool $consolidateBookmarks = true,
public bool $deduplicatePages = false,
public bool $rewriteLinks = true,
public int $maxInputs = 100,
public int $maxBytesPerInput = 100_000_000,
)
public static function default(): self
public static function basic(): self
public function isValid(): bool
public function hasOptimizations(): bool
public function __construct(?PdfSplitter $splitter = null)
public function splitByStructure(
string $pdfData,
float $headingFontThreshold = 14.0,
): SplitResult

SmartMerger::merge() 執行一個固定管線,從外部觀察如下。

  1. 空的輸入清單會引發 InvalidArgumentException。接著輸入數量受 maxInputs 約束;超出時引發 OverflowException
  2. 每個輸入在使用前會依 maxBytesPerInput 檢查大小。當輸入宣告了頁面範圍時,會先透過 Pro splitter 縮減為所選頁面,然後只提供那些頁面。
  3. 當啟用 deduplicatePages 時,每份輸入文件的完整位元組字串會以非密碼學的 xxh128 函式計算指紋。位元組與較早輸入完全相符的輸入會被捨棄。去重作用於整份文件且以位元組精確比對。
  4. 基礎組裝委派給 Pro PdfSplitter::mergeDocuments() 引擎,它會將每個輸入重新編號至一個連續的物件空間,並產出一個真實的交叉參照表。
  5. 當啟用 consolidateBookmarks 且至少一個輸入帶有非空標籤時,會套用書籤整併。會插入一個最小的 /Outlines dictionary,由文件 catalog 連結,並依合併順序為每個輸入建立一個 outline 項目。
  6. 當啟用 rewriteLinks 時,會掃描合併輸出中的 /S /GoTo 動作並回報其數量。

SmartMergeResult 回報合併後的位元組以及統計。totalPages 來自基礎合併。sourceCount 是原始輸入數量,於去重之前取得。mergedSize 是輸出的位元組長度。bookmarksAdded 只計數提供了非空標籤的輸入。duplicatesRemoved 計數被捨棄的整份輸入。linksRewritten 是偵測到的 GoTo 數量。inputLabels 依合併順序列出解析後的標籤。isValid() 檢查 %PDF 標頭;hasOptimizations() 在有重複被移除或有連結被計數時為 true。

每個 outline 項目以 /Title 承載輸入標籤,並依 ISO 32000-2:2020 §7.3.4.2 逸出為 PDF literal string。會先將反斜線加倍、逸出括號、具名控制位元組使用其既定序列,任何剩餘的不可列印位元組則轉為三位數八進位逸出。因此惡意標籤無法使 literal-string 分隔符失去同步,也無法注入物件結構。標籤為空的輸入會取得 Document N 的佔位標題,從 1 起算。

舊版 Core PdfMerger::merge() 在此版本中是刻意的 fail-closed stub;SmartMerger 從不呼叫它。基礎合併改為透過 Pro PdfSplitter::mergeDocuments() 執行,因此合併後的檔案會依 ISO 32000-2:2020 §7.5.4 為每個間接物件各一筆項目、承載一個位元組精確的交叉參照表。決定性遵循 Pro splitter 的既載設定檔:相同的輸入與設定會產生穩定的位元組串流。

SemanticSplitter::splitByStructure() 掃描頁面內容串流中大於或等於 headingFontThreshold(預設 14.0)的 Tf 設定字型運算子,並將每個這樣的頁面視為區段起點。邊界會轉換為頁面範圍並委派給 Pro PdfSplitter::split()。當未偵測到邊界時,整份文件會作為單一區段回傳。輸入必須以 %PDF 開頭並維持在 100 MB 界限內。

  • 空的輸入清單會在任何組裝之前以 InvalidArgumentException 失敗。
  • 輸入數量超過 maxInputs(預設 100),或任何輸入超過 maxBytesPerInput(預設 100 MB),會以 OverflowException 失敗。兩個界限都是刻意的 fail-closed 拒絕,而非暫時性錯誤。
  • 去重作用於整份文件且以位元組精確比對。兩個算繪結果相同但有任何位元組不同的輸入都會被保留,且儘管 deduplicatePages 名稱偏向頁面導向,duplicatesRemoved 計數的是被捨棄的整份輸入。
  • sourceCount 反映的是原始輸入數量,而非去重之後的文件數量。
  • 書籤整併只在至少一個輸入具有非空標籤時才觸發。若 consolidateBookmarks 為 true 但每個標籤皆為空,則不會寫出任何 /Outlines 物件。
  • 注入的 outline 項目帶有標題以及 /Parent/Prev/Next 樹狀連結;在此版本中它們不會內嵌明確的 /Dest 目的地。
  • 連結改寫只計數 /S /GoTo 動作;它不會跨重新編號的物件重新指向目的地。請將 linksRewritten 視為偵測數量。
  • SemanticSplitter 的偵測是語彙式的。它以 Tf 字型大小運算子為依據,因此純影像或以不尋常方式編碼的頁面不會產生邊界,會回傳單一整份文件區段。

此模組不進行任何密碼學運算,因此不存在任何 FIPS 模式專屬行為。用於去重的 xxh128 內容指紋是非密碼學的變更偵測雜湊,不具備任何完整性或證據上的分量。

主張標準條款
整併書籤以 /Outlines dictionary 寫出並由文件 catalog 連結ISO 32000-2:2020§7.7.2
基礎合併為每個間接物件產出位元組精確的交叉參照表ISO 32000-2:2020§7.5.4
outline 項目標題逸出為 PDF literal string,並處理反斜線與括號ISO 32000-2:2020§7.3.4.2
完整的跨文件連結重新解析不支援(僅偵測 GoTo)
明確的各區段 outline 目的地此版本不產出

所有條款皆為改寫;NextPDF 不重製規範性文字。這些是能力陳述,而非認證;NextPDF 未持有任何認證,亦不授予任何認證。

  • 在 Pro 套件中的供應狀態:SmartMergerMergeInputSmartMergeConfigSmartMergeResultSemanticSplitter 自 2.2.0 起提供。全部在 nextpdf/pro 3.1.0 中為現行版本。
  • 基礎合併委派給 Pro PdfSplitter::mergeDocuments()。舊版 Core PdfMerger::merge() 在此版本中是 fail-closed stub,從不被呼叫。
  • 只有在輸入可能是位元組完全相同的整份文件時才啟用 deduplicatePages;它不會合併近似重複或重新編碼的副本。
  • 純串接使用 SmartMergeConfig::basic(),書籤加連結掃描使用 ::default()
  • 合併不可信輸入時請攔截 OverflowException;數量與大小界限是刻意的拒絕。
  • 簡單的頁面範圍切分請直接優先使用 Pro PdfSplitter;只有在需要標題驅動的分段時才採用 SemanticSplitter

本頁只記載外部可觀察的行為以及受支援的公開 API 介面。內部命名空間路徑、輔助類別、機制表格、runbook 檔名與工單前綴皆不在範圍內。