跳到內容
getnextpdf.com

Pro 版本

AST — 深入參考

本頁是 Pro AST 模組的深度參考,涵蓋公開的 build、cache、mutation、write 與 emit 介面、它們的行為合約,以及失敗模式。此模組會將載入的 PDF 剖析為不可變的 AstDocument 樹,套用有記錄的記憶體內變動,並寫入以 overlay 為基礎的增量更新。AstDocumentAstNode 是位於 NextPDF\Ast 命名空間的 Core 值型別;此模組會產生並消費它們。

此能力隨 NextPDF Pronextpdf/pro)出貨,並透過 Pro 層級的授權封套啟用。未持有該授權的部署不會載入此能力的類別。比較版本並取得授權

沒有逐功能的授權旗標。這是 Pro 版本的能力。建構行為完全由 AstBuildOptions 治理。

符號參數預設行為回傳拋出或失敗於備註
AstBuilder::__constructPdfReader $reader, AstBuildOptions $options, ?AstCache $cache = null將載入的 reader 綁定至建構選項;快取為可選AstBuildernull 快取代表每次 build() 呼叫都會重建。
AstBuilder::buildstring $sourceHash(PDF 位元組的完整 SHA-256 十六進位值)快取查詢、加密拒絕、結構樹路徑、untagged 回退、邊界框附加、快取存放AstDocumentAstUnsupportedEncryptionException, AstBuildLimitException, AstBuildTimeoutException快取命中會直接回傳,不重新剖析。
AstBuildOptions::__construct?int $pageRangeStart = null, ?int $pageRangeEnd = null, int $maxNodes = 100_000, int $maxDepth = 200, ?int $estimatedTokenBudget = null, int $maxMemoryBytes = 268435456, float $timeoutSeconds = 30.0, bool $useHeuristic = false不可變的組態值物件AstBuildOptionsestimatedTokenBudget 是資訊性提示;並不會被強制執行。
AstBuildOptions::pageRangeContainsint $pageIndex當以 0 為基底的索引落在所設定範圍內時為 Trueboolnull 邊界為開放式;兩者皆為 null 代表所有頁面。
AstBuildOptions::hash對所有選項值計算的穩定 SHA-256string相同的值在不同實例間會產生相同的雜湊;用作快取鍵的片段。
AstCache::__constructCacheInterface $backend包裝任意 PSR-16 後端AstCache
AstCache::buildKeystring $sourceHash, AstBuildOptions $options鍵 = nextpdf_ast_v1_ + 來源雜湊前 32 個十六進位字元 + _ + 選項雜湊前 16 個十六進位字元string選項變更會自動使已快取的結果失效。
AstCache::getstring $cacheKey透過嚴格的逐欄位驗證解碼 JSON 載荷?AstDocument絕不拋出;失敗時回傳 null格式錯誤或遭竄改的載荷會以快取未命中的方式安全失敗(fail closed)。
AstCache::setstring $cacheKey, AstDocument $document以 24 小時 TTL 儲存 JSON,隨後立即回讀驗證voidAstWriteVerificationException(Exception 命名空間)後端寫入失敗或往返(round-trip)失敗會拋出。
AstCache::deletestring $cacheKey盡力而為的移除void絕不拋出後端刪除失敗會被吞掉。
AstCache::hasstring $cacheKey盡力而為的存在性檢查bool絕不拋出;失敗時回傳 false
AstMutator::updateNodeAstDocument $document, string $nodeId, array $updates取代 text_content,記錄一筆 Updated 項目AstDocument(新實例)InvalidArgumentException只會套用 text_content 鍵;未知的鍵會被忽略。
AstMutator::deleteNodeAstDocument $document, string $nodeId從記憶體內的樹移除該節點,記錄一筆 Deleted 項目AstDocument(新實例)InvalidArgumentException僅為記憶體內移除;請參閱下方的塗銷(redaction)注意事項。
AstMutator::getMutationLog回傳共用的日誌實例MutationLog將同一個日誌傳給 AstWriter
AstMutator::resetLog捨棄所有已記錄的變動void開啟一份全新的日誌。
MutationLogrecord, all, isEmpty, count, forNode, mutatedNodeIds僅可附加的記憶體內日誌,保留插入順序視方法而定forNode 會回傳某節點最近一筆項目;以最後一筆為準。
MutationEntry::__constructstring $nodeId, MutationType $type, ?AstNode $originalNode, ?AstNode $mutatedNode, DateTimeImmutable $timestamp單一變動的不可變紀錄MutationEntryoriginalNode 對 Inserted 為 null;mutatedNode 對 Deleted 為 null。
MutationType列舉案例 Updated, Inserted, Deleted以字串為底的分類OVERLAY 下的 Deleted 會隱藏內容;並不會抹除位元組。
AstWriter::writestring $originalPdfBytes, MutationLog $log附加一筆增量更新,其 overlay 串流涵蓋被變動的邊界框string(修改後的 PDF 位元組)AstWriteException空的日誌會原封不動回傳輸入。Inserted 項目與沒有邊界框的項目會被略過。
AstWriter::writeAndVerifystring $originalPdfBytes, MutationLog $log執行 write(),接著進行結構性的輸出檢查string(已驗證的 PDF 位元組)AstWriteException, AstWriteVerificationException(Writer 命名空間)驗證是結構性的,而非語意性的。
AstPdfEmitter::emitAstNode $root, BinaryBuffer $buffer, ObjectRegistry $registry, array $pageObjects為所提供的樹寫入 StructTreeRootStructElem 鏈以及 ParentTreeEmitResultAstEmitExceptionroot 必須是具有子節點的 Document 節點。用於結構樹驗證的往返 emitter。
EmitResult::__constructint $structTreeRootObject, int $rootElementObject, int $parentTreeObject, int $elementObjectCount, int $parentTreeNextKey已發出物件識別碼的不可變紀錄EmitResult
public function build(string $sourceHash): AstDocument
public function updateNode(AstDocument $document, string $nodeId, array $updates): AstDocument
public function deleteNode(AstDocument $document, string $nodeId): AstDocument
public function write(string $originalPdfBytes, MutationLog $log): string
public function writeAndVerify(string $originalPdfBytes, MutationLog $log): string
  • NextPDF\Pro\Ast\Exception\AstException 繼承 RuntimeException——建構階層的基底。
  • AstBuildLimitException 繼承 AstException——超出了節點、深度或記憶體上限。
  • AstBuildTimeoutException 繼承 AstBuildLimitException——牆鐘建構逾時已到。
  • AstNoStructTreeException 繼承 AstException——不存在結構樹。AstBuilder::build() 會在內部攔截它並回退;build() 的呼叫者不會觀察到它。
  • AstUnsupportedEncryptionException 繼承 AstException——輸入的 PDF 已加密。
  • NextPDF\Pro\Ast\Exception\AstWriteVerificationException 繼承 AstException——快取寫入驗證失敗。
  • NextPDF\Pro\Ast\Writer\AstWriteException 繼承 RuntimeException——writer 輸入或結構失敗。
  • NextPDF\Pro\Ast\Writer\AstWriteVerificationException 繼承 AstWriteException——寫入後的結構性驗證失敗。

有兩個不同的 AstWriteVerificationException 類別存在於不同的命名空間。AstCache::set() 會拋出 Exception 命名空間的類別;AstWriter::writeAndVerify() 會拋出 Writer 命名空間的類別。請在 catch 子句中對應正確的命名空間。

AstBuilder::build($sourceHash) 需要來源位元組的完整 SHA-256 十六進位值。其管線為:可選的快取查詢、加密拒絕、結構樹路徑、untagged 回退、邊界框附加、可選的快取存放。

快取鍵會將來源雜湊與 AstBuildOptions 雜湊結合。選項雜湊在具相同值的不同實例間是穩定的,因此相同的輸入與選項會回傳同一棵樹。當未提供快取時,每次呼叫都會重建。快取載荷為 JSON,絕不使用原生 PHP 序列化:讀取路徑會驗證每個欄位並只實例化 AST 值型別,因此遭下毒的快取項目無法觸發物件注入,而會退化為快取未命中。

結構樹路徑會在存在結構樹時執行。資源上限——節點數、深度、記憶體增量以及牆鐘時間——會在讀取結構樹期間被強制執行,並引發 AstBuildLimitExceptionAstBuildTimeoutException。若讀取器回報沒有結構樹,建構器會切換到 untagged 路徑:當 useHeuristic 為 true 時使用啟發式建構器,否則使用裸回退建構器。邊界框是透過分析每個範圍內頁面的內容串流來附加;無法剖析其內容串流的頁面會被略過,並讓樹的其餘部分維持完整。

AstNode 是不可變的。樹更新會由下而上重建受影響的節點;未變更的子樹會以識別性(identity)回傳。AstMutator 遵循相同的合約:每次變動都會回傳一個新的 AstDocument,只重建從 root 到目標的路徑,並在共用的 MutationLog 中記錄一筆 MutationEntry

AstWriter 會以 OVERLAY 模式將 MutationLog 套用為僅可附加的增量更新:新的 overlay 內容串流、更新後的頁面物件、只涵蓋新物件的交叉參照區段,以及其 /Prev 指向先前 startxref 的 trailer。原始位元組會維持完整,符合 ISO 32000-2:2020, 7.5.6 的增量更新模型。為 Updated 項目繪製的取代文字會在文字字串(literal string)中跳脫 \(),符合 ISO 32000-2:2020, 7.3.4.2。

AstPdfEmitter::emit() 是讀取結構樹的對稱反向操作:讀取器所產生的樹能往返為結構等價的樹,差異僅在於 node-id 重新編號與已記載的正規化(canonicalisation)類別。節點上既有的 MCID 會逐字重新發出,絕不重新配置。

  • 加密的輸入會在任何樹工作之前被拒絕;加密的 PDF 不會有部分樹結果。請先解密。
  • 資源上限:最大節點數(預設 100,000)、最大深度(預設 200)、最大記憶體(預設 256 MiB)、牆鐘逾時(預設 30 s)。超出某個上限會引發 AstBuildLimitException;逾時會引發其子類別 AstBuildTimeoutException
  • 頁面範圍以 0 為基底且為包含式;null 邊界代表所有頁面。
  • 無法剖析其內容串流的頁面會在邊界框附加期間被略過;樹的其餘部分不受影響。
  • AstCache::get() 絕不拋出:格式錯誤、遭竄改或非字串的載荷會回傳 null 並強制重建。當後端寫入或立即回讀失敗時,AstCache::set() 會明確地失敗(fail loudly)。
  • 當找不到 node id 時,AstMutator 會引發 InvalidArgumentException。未知的更新鍵會被靜默忽略;只會套用 text_content
  • 當輸入缺少 %PDF- 標頭或可定位的 startxref 時,AstWriter::write() 會引發 AstWriteException。沒有邊界框的項目會被靜默略過。無法透過物件掃描定位的頁面——例如在壓縮交叉參照串流下——會被略過;若無法套用任何 overlay,則會原封不動回傳輸入位元組。
  • OVERLAY 輸出並非塗銷(redaction)。白色矩形與重繪的文字是附加上去的;原始內容位元組仍留存於檔案中,且可透過原始擷取還原。請勿將其用於 GDPR Art. 17 抹除或法律塗銷。來源樹中存在一個 reconstruct 模式的 writer,但被標記為內部使用、尚未達生產就緒,且不在受支援的 API 介面範圍內。
  • overlay 幾何假設為 A4 直向(595 x 842 pt),因為 writer 不會讀取頁面的 MediaBox。在非 A4 頁面上 overlay 可能會略微錯位;輸出仍然在結構上有效。
  • writeAndVerify() 只檢查結構:標頭、結尾的 %%EOF 以及輸出增長。它不會在語意上重新剖析被變動的文件。
  • 當 root 不是 Document 節點或沒有子節點時,AstPdfEmitter::emit() 會引發 AstEmitException。本次發行不會發出 OBJR(annotation)伴隨項目。
  • 此模組不執行任何密碼學作業,也不定義任何 FIPS 專屬行為。SHA-256 僅作為快取鍵的內容定址而出現。

結構樹路徑會讀取 ISO 32000-2 所定義的 tagged-PDF 邏輯結構機制;撰寫時可用的 RAG 語料庫並未包含邏輯結構條款,因此該陳述是以來源標註為依據的產品層級說明。writer 的增量更新版面遵循 ISO 32000-2:2020, 7.5.6(見下方引用),其文字字串跳脫遵循 ISO 32000-2:2020, 7.3.4.2(見下方引用)。

這些陳述描述的是相對於所引用條款的能力。NextPDF 未持有任何一致性認證,而支援某條款並不構成認證主張。

  • 每個載入的 PdfReader 組合一個 AstBuilder。跨多次建構重用同一個 AstCache 以攤提剖析成本;鍵的設計使選項變更能自我失效。
  • AstMutatorAstWriter 之間共用一個 MutationLog,如此 writer 便能精確套用所記錄的工作階段。在各自獨立的編輯工作階段之間呼叫 resetLog()
  • 當版面推導出的分組優於裸回退樹時,為 untagged 文件將 useHeuristic 設為 true。
  • 對於相同的位元組與選項,建構具決定性;可在快照式測試中依賴這一點。
  • 透過 NextPDF\Pro\Ast\Exception 階層攔截建構失敗,並透過 NextPDF\Pro\Ast\Writer 階層攔截寫入失敗;兩者在 RuntimeException 之下並不共用基底。

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