Pro Edition
AST — Ausführliche Referenz
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Diese Seite ist die ausführliche Referenz für das Pro-AST-Modul. Sie behandelt die öffentlichen Build-, Cache-, Mutations-, Schreib- und Emit-Oberflächen, ihre Verhaltensverträge und ihre Fehlermodi. Das Modul parst eine geladene PDF in einen unveränderlichen AstDocument-Baum, wendet protokollierte In-Memory-Mutationen an und schreibt overlay-basierte inkrementelle Updates. AstDocument und AstNode sind Core-Wertobjekte im Namespace NextPDF\Ast; dieses Modul erzeugt und konsumiert sie.
Verfügbarkeit & Lizenzierung
Abschnitt betitelt „Verfügbarkeit & Lizenzierung“Diese Fähigkeit wird in NextPDF Pro (nextpdf/pro) ausgeliefert und aktiviert sich mit einem Lizenzumschlag der Pro-Stufe. Eine Bereitstellung ohne diese Berechtigung lädt die Klassen der Fähigkeit nicht. Editionen vergleichen und Lizenz erwerben.
Es gibt kein Lizenz-Flag pro Feature. Dies ist eine Fähigkeit der Pro-Edition. Das Build-Verhalten wird vollständig durch AstBuildOptions bestimmt.
Öffentliche API-Oberfläche
Abschnitt betitelt „Öffentliche API-Oberfläche“| Symbol | Parameter | Standardverhalten | Rückgabe | Wirft oder scheitert mit | Hinweise |
|---|---|---|---|---|---|
AstBuilder::__construct | PdfReader $reader, AstBuildOptions $options, ?AstCache $cache = null | Bindet einen geladenen Reader an Build-Optionen; Caching ist optional | AstBuilder | — | Ein Null-Cache bedeutet, dass jeder build()-Aufruf neu aufbaut. |
AstBuilder::build | string $sourceHash (vollständiger SHA-256-Hex der PDF-Bytes) | Cache-Suche, Verschlüsselungsablehnung, Strukturbaum-Pfad, Fallback für ungetaggte Dokumente, Anfügen von Begrenzungsrahmen, Cache-Speicherung | AstDocument | AstUnsupportedEncryptionException, AstBuildLimitException, AstBuildTimeoutException | Ein Cache-Treffer liefert ohne erneutes Parsen zurück. |
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 | Unveränderliches Konfigurations-Wertobjekt | AstBuildOptions | — | estimatedTokenBudget ist ein informativer Hinweis; er wird nicht durchgesetzt. |
AstBuildOptions::pageRangeContains | int $pageIndex | True, wenn der 0-basierte Index innerhalb des konfigurierten Bereichs liegt | bool | — | Null-Grenzen sind offen; beide null bedeutet alle Seiten. |
AstBuildOptions::hash | — | Stabiler SHA-256 über alle Optionswerte | string | — | Gleiche Werte ergeben instanzübergreifend gleiche Hashes; wird als Cache-Schlüssel-Segment verwendet. |
AstCache::__construct | CacheInterface $backend | Umschließt ein beliebiges PSR-16-Backend | AstCache | — | — |
AstCache::buildKey | string $sourceHash, AstBuildOptions $options | Schlüssel = nextpdf_ast_v1_ + erste 32 Hex des Quell-Hashes + _ + erste 16 Hex des Options-Hashes | string | — | Optionsänderungen invalidieren zwischengespeicherte Ergebnisse automatisch. |
AstCache::get | string $cacheKey | Dekodiert eine JSON-Nutzlast über strikte Validierung pro Feld | ?AstDocument | Wirft nie; Fehler liefern null | Fehlerhafte oder manipulierte Nutzlasten scheitern geschlossen als Cache-Fehltreffer. |
AstCache::set | string $cacheKey, AstDocument $document | Speichert JSON mit einer 24-Stunden-TTL und verifiziert dann durch sofortiges Zurücklesen | void | AstWriteVerificationException (Exception-Namespace) | Ein Backend-Schreibfehler oder ein fehlgeschlagener Roundtrip löst aus. |
AstCache::delete | string $cacheKey | Best-Effort-Entfernung | void | Wirft nie | Backend-Löschfehler werden verschluckt. |
AstCache::has | string $cacheKey | Best-Effort-Existenzprüfung | bool | Wirft nie; Fehler liefern false | — |
AstMutator::updateNode | AstDocument $document, string $nodeId, array $updates | Ersetzt text_content, erfasst einen Updated-Eintrag | AstDocument (neue Instanz) | InvalidArgumentException | Nur der Schlüssel text_content wird angewendet; unbekannte Schlüssel werden ignoriert. |
AstMutator::deleteNode | AstDocument $document, string $nodeId | Entfernt den Knoten aus dem In-Memory-Baum, erfasst einen Deleted-Eintrag | AstDocument (neue Instanz) | InvalidArgumentException | Nur In-Memory-Entfernung; siehe den Schwärzungshinweis unten. |
AstMutator::getMutationLog | — | Liefert die gemeinsame Log-Instanz | MutationLog | — | Übergeben Sie dasselbe Log an AstWriter. |
AstMutator::resetLog | — | Verwirft alle erfassten Mutationen | void | — | Beginnt ein frisches Log. |
MutationLog | record, all, isEmpty, count, forNode, mutatedNodeIds | Nur-Anfügen-In-Memory-Log, Einfügereihenfolge bleibt erhalten | je Methode | — | forNode liefert den jüngsten Eintrag für einen Knoten; der letzte Eintrag gewinnt. |
MutationEntry::__construct | string $nodeId, MutationType $type, ?AstNode $originalNode, ?AstNode $mutatedNode, DateTimeImmutable $timestamp | Unveränderlicher Datensatz einer Mutation | MutationEntry | — | originalNode ist null bei Inserted; mutatedNode ist null bei Deleted. |
MutationType | Enum-Fälle Updated, Inserted, Deleted | String-basierte Klassifizierung | — | — | Deleted unter OVERLAY verbirgt Inhalt; es löscht keine Bytes. |
AstWriter::write | string $originalPdfBytes, MutationLog $log | Fügt ein inkrementelles Update an, dessen Overlay-Streams die mutierten Begrenzungsrahmen abdecken | string (modifizierte PDF-Bytes) | AstWriteException | Ein leeres Log liefert die Eingabe unverändert zurück. Inserted-Einträge und Einträge ohne Begrenzungsrahmen werden übersprungen. |
AstWriter::writeAndVerify | string $originalPdfBytes, MutationLog $log | Führt write() aus, dann eine strukturelle Ausgabeprüfung | string (verifizierte PDF-Bytes) | AstWriteException, AstWriteVerificationException (Writer-Namespace) | Die Verifizierung ist strukturell, nicht semantisch. |
AstPdfEmitter::emit | AstNode $root, BinaryBuffer $buffer, ObjectRegistry $registry, array $pageObjects | Schreibt einen StructTreeRoot, eine StructElem-Kette und einen ParentTree für den übergebenen Baum | EmitResult | AstEmitException | Die Wurzel muss ein Document-Knoten mit Kindern sein. Roundtrip-Emitter für die Strukturbaum-Verifizierung. |
EmitResult::__construct | int $structTreeRootObject, int $rootElementObject, int $parentTreeObject, int $elementObjectCount, int $parentTreeNextKey | Unveränderlicher Datensatz der emittierten Objektbezeichner | 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): stringAusnahmehierarchie
Abschnitt betitelt „Ausnahmehierarchie“NextPDF\Pro\Ast\Exception\AstExceptionextendsRuntimeException— Basis der Build-Hierarchie.AstBuildLimitExceptionextendsAstException— eine Knoten-, Tiefen- oder Speicherobergrenze wurde überschritten.AstBuildTimeoutExceptionextendsAstBuildLimitException— das Wanduhr-Build-Timeout ist abgelaufen.AstNoStructTreeExceptionextendsAstException— kein Strukturbaum vorhanden.AstBuilder::build()fängt sie intern ab und weicht aus; Aufrufer vonbuild()beobachten sie nicht.AstUnsupportedEncryptionExceptionextendsAstException— die Eingabe-PDF ist verschlüsselt.NextPDF\Pro\Ast\Exception\AstWriteVerificationExceptionextendsAstException— die Cache-Schreibverifizierung ist fehlgeschlagen.NextPDF\Pro\Ast\Writer\AstWriteExceptionextendsRuntimeException— Writer-Eingabe- oder Strukturfehler.NextPDF\Pro\Ast\Writer\AstWriteVerificationExceptionextendsAstWriteException— strukturelle Verifizierung nach dem Schreiben fehlgeschlagen.
Zwei verschiedene AstWriteVerificationException-Klassen existieren in unterschiedlichen Namespaces. AstCache::set() löst die Klasse aus dem Exception-Namespace aus; AstWriter::writeAndVerify() löst die Klasse aus dem Writer-Namespace aus. Passen Sie den Namespace in catch-Klauseln an.
Verhaltensvertrag
Abschnitt betitelt „Verhaltensvertrag“AstBuilder::build($sourceHash) erfordert den vollständigen SHA-256-Hex der Quell-Bytes. Die Pipeline lautet: optionale Cache-Suche, Verschlüsselungsablehnung, Strukturbaum-Pfad, Fallback für ungetaggte Dokumente, Anfügen von Begrenzungsrahmen, optionale Cache-Speicherung.
Der Cache-Schlüssel kombiniert den Quell-Hash mit dem AstBuildOptions-Hash. Der Options-Hash ist über Instanzen mit identischen Werten stabil, sodass identische Eingaben und Optionen denselben Baum zurückliefern. Wenn kein Cache bereitgestellt wird, baut jeder Aufruf neu auf. Zwischengespeicherte Nutzlasten sind JSON, niemals native PHP-Serialisierung: Der Lesepfad validiert jedes Feld und instanziiert nur AST-Wertobjekte, sodass ein vergifteter Cache-Eintrag keine Objektinjektion auslösen kann und zu einem Cache-Fehltreffer degradiert.
Der Strukturbaum-Pfad läuft, wenn ein Strukturbaum vorhanden ist. Ressourcenobergrenzen — Knotenanzahl, Tiefe, Speicherdelta und Wanduhrzeit — werden während des Strukturbaum-Lesens durchgesetzt und lösen AstBuildLimitException oder AstBuildTimeoutException aus. Meldet der Reader keinen Strukturbaum, wechselt der Builder auf den ungetaggten Pfad: den heuristischen Builder, wenn useHeuristic true ist, andernfalls den bloßen Fallback-Builder. Begrenzungsrahmen werden angefügt, indem der Content-Stream jeder Seite im Bereich analysiert wird; eine Seite, deren Content-Stream nicht geparst werden kann, wird übersprungen und lässt den Rest des Baums intakt.
AstNode ist unveränderlich. Baumaktualisierungen bauen betroffene Knoten von unten nach oben neu auf; unveränderte Teilbäume werden per Identität zurückgeliefert. AstMutator folgt demselben Vertrag: Jede Mutation liefert ein neues AstDocument, baut nur den Pfad von der Wurzel zum Ziel neu auf und erfasst einen MutationEntry im gemeinsamen MutationLog.
AstWriter wendet ein MutationLog im OVERLAY-Modus als reines Anfüge-Inkrementell-Update an: neue Overlay-Content-Streams, aktualisierte Seitenobjekte, ein Querverweisabschnitt, der nur neue Objekte abdeckt, und einen Trailer, dessen /Prev auf das vorherige startxref zeigt. Die ursprünglichen Bytes bleiben intakt, gemäß dem Inkrementell-Update-Modell von ISO 32000-2:2020, 7.5.6. Ersatztext, der für Updated-Einträge gezeichnet wird, maskiert \, ( und ) in literalen Zeichenketten, gemäß ISO 32000-2:2020, 7.3.4.2.
AstPdfEmitter::emit() ist die symmetrische Umkehrung des Strukturbaum-Lesens: Vom Reader erzeugte Bäume durchlaufen einen Roundtrip zu strukturell äquivalenten Bäumen, abgesehen von der Neunummerierung der Knoten-IDs und dokumentierten Kanonisierungsklassen. Auf Knoten vorhandene MCIDs werden wörtlich neu emittiert, niemals neu zugewiesen.
Grenzfälle & Fehlermodi
Abschnitt betitelt „Grenzfälle & Fehlermodi“- Verschlüsselte Eingaben werden vor jeglicher Baumarbeit abgelehnt; es gibt kein Teilbaum-Ergebnis für verschlüsselte PDFs. Entschlüsseln Sie zuerst.
- Ressourcenobergrenzen: max. Knoten (Standard 100,000), max. Tiefe (Standard 200), max. Speicher (Standard 256 MiB), Wanduhr-Timeout (Standard 30 s). Das Überschreiten einer Obergrenze löst
AstBuildLimitExceptionaus; das Timeout löstAstBuildTimeoutException, eine Unterklasse, aus. - Der Seitenbereich ist 0-basiert und inklusiv; Null-Grenzen bedeuten alle Seiten.
- Eine Seite, deren Content-Stream nicht geparst werden kann, wird beim Anfügen von Begrenzungsrahmen übersprungen; der Rest des Baums bleibt unberührt.
AstCache::get()wirft nie: fehlerhafte, manipulierte oder Nicht-String-Nutzlasten liefern null und erzwingen einen Neuaufbau.AstCache::set()scheitert lautstark, wenn der Backend-Schreibvorgang oder das sofortige Zurücklesen fehlschlägt.AstMutatorlöstInvalidArgumentExceptionaus, wenn die Knoten-ID nicht gefunden wird. Unbekannte Update-Schlüssel werden stillschweigend ignoriert; nurtext_contentwird angewendet.AstWriter::write()löstAstWriteExceptionaus, wenn der Eingabe ein%PDF--Header oder ein auffindbaresstartxreffehlt. Einträge ohne Begrenzungsrahmen werden stillschweigend übersprungen. Seiten, die per Objekt-Scan nicht lokalisiert werden können — beispielsweise bei komprimierten Querverweis-Streams —, werden übersprungen; wenn kein Overlay angewendet werden kann, werden die Eingabe-Bytes unverändert zurückgeliefert.- OVERLAY-Ausgabe ist keine Schwärzung. Das weiße Rechteck und der neu gezeichnete Text werden angefügt; die ursprünglichen Inhaltsbytes verbleiben in der Datei und sind durch Rohextraktion wiederherstellbar. Verwenden Sie es nicht für die Löschung nach GDPR Art. 17 oder rechtliche Schwärzung. Ein Reconstruct-Modus-Writer existiert im Quellbaum, ist jedoch als intern markiert, nicht produktionsreif und außerhalb der unterstützten API-Oberfläche.
- Die Overlay-Geometrie nimmt A4-Hochformat (595 x 842 pt) an, da der Writer die MediaBox der Seite nicht liest. Auf Nicht-A4-Seiten kann das Overlay leicht falsch ausgerichtet sein; die Ausgabe bleibt strukturell gültig.
writeAndVerify()prüft nur die Struktur: Header, abschließendes%%EOFund Ausgabewachstum. Es parst das mutierte Dokument nicht semantisch neu.AstPdfEmitter::emit()löstAstEmitExceptionaus, wenn die Wurzel kein Document-Knoten ist oder keine Kinder hat. OBJR-Begleiteinträge (Annotation) werden in diesem Release nicht emittiert.- Dieses Modul führt keine kryptografischen Operationen durch und definiert kein FIPS-spezifisches Verhalten. SHA-256 erscheint nur als Inhaltsadressierung für Cache-Schlüssel.
Konformität
Abschnitt betitelt „Konformität“Der Strukturbaum-Pfad liest die im tagged-PDF definierten logischen Strukturfunktionen gemäß ISO 32000-2; das zum Autorenzeitpunkt verfügbare RAG-Korpus enthält die Klauseln zur logischen Struktur nicht, sodass diese Aussage produktbasiert aus den Quellannotationen stammt. Das Inkrementell-Update-Layout des Writers folgt ISO 32000-2:2020, 7.5.6 (unten zitiert), und seine Maskierung literaler Zeichenketten folgt ISO 32000-2:2020, 7.3.4.2 (unten zitiert).
Diese Aussagen beschreiben die Fähigkeit gegenüber den zitierten Klauseln. NextPDF besitzt keine Konformitätszertifizierung, und die Unterstützung einer Klausel ist keine Zertifizierungsaussage.
Entwicklungshinweise
Abschnitt betitelt „Entwicklungshinweise“- Erstellen Sie einen
AstBuilderje geladenemPdfReader. Verwenden Sie einenAstCacheüber Builds hinweg wieder, um das Parsen zu amortisieren; das Schlüsseldesign macht Optionsänderungen selbstinvalidierend. - Teilen Sie ein
MutationLogzwischen einemAstMutatorund demAstWriter, damit der Writer genau die erfasste Sitzung anwendet. Rufen SieresetLog()zwischen unabhängigen Bearbeitungssitzungen auf. - Setzen Sie
useHeuristicfür ungetaggte Dokumente auf true, wenn eine layoutbasierte Gruppierung dem bloßen Fallback-Baum vorzuziehen ist. - Builds sind bei identischen Bytes und Optionen deterministisch; verlassen Sie sich darauf für Snapshot-artige Tests.
- Fangen Sie Build-Fehler über die
NextPDF\Pro\Ast\Exception-Hierarchie und Schreibfehler über dieNextPDF\Pro\Ast\Writer-Hierarchie ab; die beiden teilen keine Basis unterhalb vonRuntimeException.
Veröffentlichungsgrenze
Abschnitt betitelt „Veröffentlichungsgrenze“Diese Seite dokumentiert ausschließlich extern beobachtbares Verhalten und die unterstützte öffentliche API-Oberfläche. Interne Namespace-Pfade, Hilfsklassen, Mechanismustabellen, Runbook-Dateinamen und Ticket-Präfixe liegen außerhalb des Umfangs.