Pro エディション
AST — 詳細リファレンス
このページは、Pro AST モジュールの詳細リファレンスです。公開されているビルド、キャッシュ、ミューテーション、書き込み、出力の各サーフェス、それらの挙動契約、および失敗モードを扱います。本モジュールは、読み込まれた PDF を不変の AstDocument ツリーに解析し、ログ記録されたインメモリのミューテーションを適用し、オーバーレイベースの増分更新を書き込みます。AstDocument と AstNode は、NextPDF\Ast 名前空間の Core 値型であり、本モジュールはそれらを生成し消費します。
提供状況とライセンス
「提供状況とライセンス」という見出しのセクションこの機能は NextPDF Pro(nextpdf/pro)に含まれ、Pro ティアのライセンスエンベロープで有効化されます。その権限のないデプロイでは、機能のクラスは読み込まれません。エディションを比較してライセンスを取得。
機能ごとのライセンスフラグは存在しません。これは Pro エディションの機能です。ビルドの挙動は、完全に AstBuildOptions によって管理されます。
公開 API サーフェス
「公開 API サーフェス」という見出しのセクション| シンボル | パラメーター | 既定の挙動 | 戻り値 | 送出/失敗する例外 | 備考 |
|---|---|---|---|---|---|
AstBuilder::__construct | PdfReader $reader、AstBuildOptions $options、?AstCache $cache = null | 読み込み済みリーダーをビルドオプションに束縛。キャッシュは任意 | AstBuilder | — | null キャッシュの場合、build() 呼び出しごとに再構築します。 |
AstBuilder::build | string $sourceHash(PDF バイトの完全な SHA-256 16 進数) | キャッシュ参照、暗号化の拒否、構造ツリー経路、タグなしフォールバック、バウンディングボックスの付加、キャッシュ保存 | AstDocument | AstUnsupportedEncryptionException、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 | 不変の構成値オブジェクト | AstBuildOptions | — | estimatedTokenBudget は情報提供のヒントであり、強制されません。 |
AstBuildOptions::pageRangeContains | int $pageIndex | 0 始まりのインデックスが設定範囲内にあるとき true | bool | — | null の境界は開放端。両方が null の場合はすべてのページ。 |
AstBuildOptions::hash | — | すべてのオプション値に対する安定した SHA-256 | string | — | 等しい値はインスタンス間で等しいハッシュを生成。キャッシュキーのセグメントとして使用。 |
AstCache::__construct | CacheInterface $backend | 任意の PSR-16 バックエンドをラップ | AstCache | — | — |
AstCache::buildKey | string $sourceHash、AstBuildOptions $options | キー = nextpdf_ast_v1_ + ソースハッシュの先頭 32 桁 16 進 + _ + オプションハッシュの先頭 16 桁 16 進 | string | — | オプションの変更はキャッシュ結果を自動的に無効化します。 |
AstCache::get | string $cacheKey | 厳格なフィールドごとの検証を通じて JSON ペイロードをデコード | ?AstDocument | 送出しない。失敗時は null を返す | 不正または改ざんされたペイロードはキャッシュミスとしてフェイルクローズします。 |
AstCache::set | string $cacheKey、AstDocument $document | 24 時間 TTL で JSON を保存し、直後の読み戻しで検証 | void | AstWriteVerificationException(Exception 名前空間) | バックエンドの書き込み失敗、またはラウンドトリップ失敗時に送出します。 |
AstCache::delete | string $cacheKey | ベストエフォートの削除 | void | 送出しない | バックエンドの削除失敗は握りつぶされます。 |
AstCache::has | string $cacheKey | ベストエフォートの存在チェック | bool | 送出しない。失敗時は false を返す | — |
AstMutator::updateNode | AstDocument $document、string $nodeId、array $updates | text_content を置換し、Updated エントリーを記録 | AstDocument(新しいインスタンス) | InvalidArgumentException | text_content キーのみ適用。未知のキーは無視されます。 |
AstMutator::deleteNode | AstDocument $document、string $nodeId | インメモリツリーからノードを削除し、Deleted エントリーを記録 | AstDocument(新しいインスタンス) | InvalidArgumentException | インメモリ削除のみ。下記の墨消しに関する注意を参照。 |
AstMutator::getMutationLog | — | 共有ログインスタンスを返す | MutationLog | — | 同じログを AstWriter に渡してください。 |
AstMutator::resetLog | — | 記録されたすべてのミューテーションを破棄 | void | — | 新しいログを開始します。 |
MutationLog | record、all、isEmpty、count、forNode、mutatedNodeIds | 追記専用のインメモリログ。挿入順を保持 | メソッドごと | — | forNode はノードの最新エントリーを返す。最後のエントリーが優先されます。 |
MutationEntry::__construct | string $nodeId、MutationType $type、?AstNode $originalNode、?AstNode $mutatedNode、DateTimeImmutable $timestamp | 1 件のミューテーションの不変レコード | MutationEntry | — | originalNode は Inserted では null。mutatedNode は Deleted では null。 |
MutationType | enum ケース Updated、Inserted、Deleted | 文字列バックの分類 | — | — | OVERLAY 下の Deleted はコンテンツを隠すのみで、バイトを消去しません。 |
AstWriter::write | string $originalPdfBytes、MutationLog $log | オーバーレイストリームがミューテーション済みバウンディングボックスを覆う増分更新を追記 | string(変更後の PDF バイト) | AstWriteException | 空のログの場合、入力を変更せずに返します。Inserted エントリーおよびバウンディングボックスのないエントリーはスキップされます。 |
AstWriter::writeAndVerify | string $originalPdfBytes、MutationLog $log | write() を実行し、その後に構造的な出力チェック | string(検証済みの PDF バイト) | AstWriteException、AstWriteVerificationException(Writer 名前空間) | 検証は構造的なものであり、意味的ではありません。 |
AstPdfEmitter::emit | AstNode $root、BinaryBuffer $buffer、ObjectRegistry $registry、array $pageObjects | 指定ツリーに対して StructTreeRoot、StructElem チェーン、ParentTree を書き込む | EmitResult | AstEmitException | ルートは子を持つ Document ノードである必要があります。構造ツリー検証のためのラウンドトリップエミッター。 |
EmitResult::__construct | int $structTreeRootObject、int $rootElementObject、int $parentTreeObject、int $elementObjectCount、int $parentTreeNextKey | 出力されたオブジェクト識別子の不変レコード | EmitResult | — | — |
public function build(string $sourceHash): AstDocumentpublic function updateNode(AstDocument $document, string $nodeId, array $updates): AstDocumentpublic function deleteNode(AstDocument $document, string $nodeId): AstDocumentpublic function write(string $originalPdfBytes, MutationLog $log): stringpublic 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を継承 — ライターの入力または構造の失敗。NextPDF\Pro\Ast\Writer\AstWriteVerificationExceptionはAstWriteExceptionを継承 — 書き込み後の構造検証が失敗。
異なる名前空間に 2 つの別個の AstWriteVerificationException クラスが存在します。AstCache::set() は Exception 名前空間のクラスを送出し、AstWriter::writeAndVerify() は Writer 名前空間のクラスを送出します。catch 句では名前空間を一致させてください。
挙動コントラクト
「挙動コントラクト」という見出しのセクションAstBuilder::build($sourceHash) は、ソースバイトの完全な SHA-256 16 進数を必要とします。パイプラインは次のとおりです。任意のキャッシュ参照、暗号化の拒否、構造ツリー経路、タグなしフォールバック、バウンディングボックスの付加、任意のキャッシュ保存。
キャッシュキーは、ソースハッシュと AstBuildOptions のハッシュを組み合わせます。オプションハッシュは、同一の値を持つインスタンス間で安定しているため、同一の入力とオプションは同じツリーを返します。キャッシュが供給されない場合、すべての呼び出しが再構築します。キャッシュされるペイロードは JSON であり、ネイティブの PHP シリアライズは決して使用しません。読み取り経路は各フィールドを検証し、AST 値型のみをインスタンス化するため、汚染されたキャッシュエントリーはオブジェクトインジェクションを引き起こすことができず、キャッシュミスに退行します。
構造ツリー経路は、構造ツリーが存在する場合に実行されます。リソースの上限(ノード数、深さ、メモリ増分、実時間)は、構造ツリーの読み取り中に強制され、AstBuildLimitException または AstBuildTimeoutException を送出します。リーダーが構造ツリーなしと報告した場合、ビルダーはタグなし経路に切り替えます。useHeuristic が true のときはヒューリスティックビルダー、そうでないときは素のフォールバックビルダーです。バウンディングボックスは、範囲内の各ページのコンテンツストリームを解析して付加されます。コンテンツストリームを解析できないページはスキップされ、ツリーの残りはそのまま保たれます。
AstNode は不変です。ツリーの更新は影響を受けるノードをボトムアップで再構築します。変更されていないサブツリーは同一性によって返されます。AstMutator は同じ契約に従います。各ミューテーションは新しい AstDocument を返し、ルートからターゲットまでの経路のみを再構築し、共有の MutationLog に MutationEntry を記録します。
AstWriter は、MutationLog を OVERLAY モードで追記専用の増分更新として適用します。新しいオーバーレイコンテンツストリーム、更新されたページオブジェクト、新しいオブジェクトのみを対象とするクロスリファレンスセクション、そして /Prev が直前の startxref を指すトレーラーです。元のバイトは、ISO 32000-2:2020, 7.5.6 の増分更新モデルに従って、そのまま保たれます。Updated エントリーに対して描画される置換テキストは、ISO 32000-2:2020, 7.3.4.2 に従って、リテラル文字列内の \、(、) をエスケープします。
AstPdfEmitter::emit() は、構造ツリー読み取りの対称的な逆操作です。リーダーが生成したツリーは、ノード ID の再採番と文書化された正規化クラスを除いて、構造的に等価なツリーへとラウンドトリップします。ノード上に存在する MCID は、逐語的に再出力され、決して再割り当てされません。
エッジケースと失敗モード
「エッジケースと失敗モード」という見出しのセクション- 暗号化された入力は、いかなるツリー処理よりも前に拒否されます。暗号化された PDF に対する部分的なツリーの結果はありません。先に復号してください。
- リソースの上限:最大ノード数(既定 100,000)、最大深さ(既定 200)、最大メモリ(既定 256 MiB)、実時間タイムアウト(既定 30 秒)。上限を超えると
AstBuildLimitExceptionを送出し、タイムアウトはそのサブクラスであるAstBuildTimeoutExceptionを送出します。 - ページ範囲は 0 始まりで、両端を含みます。null の境界はすべてのページを意味します。
- コンテンツストリームを解析できないページは、バウンディングボックスの付加中にスキップされます。ツリーの残りは影響を受けません。
AstCache::get()は決して送出しません。不正、改ざん、または非文字列のペイロードは null を返し、再構築を強制します。AstCache::set()は、バックエンドの書き込みまたは直後の読み戻しが失敗したとき、明示的に失敗します。AstMutatorは、ノード ID が見つからない場合にInvalidArgumentExceptionを送出します。未知の更新キーは黙って無視され、text_contentのみが適用されます。AstWriter::write()は、入力に%PDF-ヘッダーまたは特定可能なstartxrefがない場合にAstWriteExceptionを送出します。バウンディングボックスのないエントリーは黙ってスキップされます。オブジェクトスキャンで特定できないページ(例えば圧縮クロスリファレンスストリームの下)はスキップされます。オーバーレイを適用できない場合、入力バイトは変更されずに返されます。- OVERLAY 出力は墨消しではありません。白い矩形と再描画されたテキストは追記されるものであり、元のコンテンツバイトはファイル内に残り、生の抽出によって復元可能です。GDPR 第 17 条の消去や法的な墨消しには使用しないでください。ソースツリーには再構築モードのライターが存在しますが、内部用と印付けされており、本番対応ではなく、サポート対象の API サーフェスの範囲外です。
- ライターはページの MediaBox を読み取らないため、オーバーレイのジオメトリは A4 縦向き(595 x 842 pt)を前提とします。A4 以外のページでは、オーバーレイがわずかにずれる可能性があります。出力は構造的に有効なままです。
writeAndVerify()は構造のみをチェックします。ヘッダー、末尾の%%EOF、および出力の増加です。ミューテーション済みドキュメントを意味的に再解析することはありません。AstPdfEmitter::emit()は、ルートが Document ノードでないか、子を持たない場合にAstEmitExceptionを送出します。OBJR(注釈)の付随エントリーは、このリリースでは出力されません。- このモジュールは暗号操作を一切実行せず、FIPS 固有の挙動を定義しません。SHA-256 は、キャッシュキーのコンテンツアドレッシングとしてのみ登場します。
構造ツリー経路は、ISO 32000-2 で定義されたタグ付き PDF の論理構造機能を読み取ります。執筆時点で利用可能な RAG コーパスには論理構造の節が含まれていないため、その記述はソースの注釈に基づく製品由来のものです。ライターの増分更新レイアウトは ISO 32000-2:2020, 7.5.6(下記に引用)に従い、そのリテラル文字列のエスケープは ISO 32000-2:2020, 7.3.4.2(下記に引用)に従います。
これらの記述は、引用された節に対する機能を説明するものです。NextPDF は適合性認証を保有しておらず、ある節へのサポートは認証の主張ではありません。
開発上の注意
「開発上の注意」という見出しのセクション- 読み込まれた
PdfReaderごとに 1 つのAstBuilderを構成してください。解析コストを分散するため、ビルド間でAstCacheを再利用します。キーの設計により、オプションの変更は自己無効化されます。 - ライターが記録されたセッションを正確に適用するよう、
AstMutatorとAstWriterの間で 1 つのMutationLogを共有してください。独立した編集セッションの間にはresetLog()を呼び出します。 - 素のフォールバックツリーよりもレイアウト由来のグルーピングが望ましい場合、タグなしドキュメントに対して
useHeuristicを true に設定してください。 - ビルドは、同一のバイトとオプションに対して決定論的です。スナップショット形式のテストではこれに依拠してください。
- ビルドの失敗は
NextPDF\Pro\Ast\Exception階層で、書き込みの失敗はNextPDF\Pro\Ast\Writer階層で捕捉してください。両者はRuntimeExceptionより下位で基底を共有しません。
公開の境界
「公開の境界」という見出しのセクションこのページは、外部から観測可能な挙動とサポート対象の公開 API サーフェスのみを文書化します。内部の名前空間パス、ヘルパークラス、メカニズムの表、ランブックのファイル名、チケットのプレフィックスは範囲外です。