Pro edisi
AST — Referensi Mendalam
Sekilas pandang
Bagian berjudul “Sekilas pandang”Halaman ini adalah referensi mendalam untuk modul AST Pro. Halaman ini mencakup permukaan publik build, cache, mutasi, write, dan emit, kontrak perilakunya, serta mode kegagalannya. Modul ini mem-parse sebuah PDF yang telah dimuat menjadi pohon AstDocument yang immutable, menerapkan mutasi in-memory yang tercatat, dan menulis pembaruan inkremental berbasis overlay. AstDocument dan AstNode adalah tipe nilai Core dalam namespace NextPDF\Ast; modul ini memproduksi dan mengonsumsinya.
Ketersediaan & lisensi
Bagian berjudul “Ketersediaan & lisensi”Kapabilitas ini dikirim dalam NextPDF Pro (nextpdf/pro) dan aktif dengan envelope lisensi tingkat Pro. Sebuah deployment tanpa entitlement tersebut tidak memuat kelas-kelas kapabilitas ini. Bandingkan edisi dan dapatkan lisensi.
Tidak ada flag lisensi per-fitur. Ini adalah kapabilitas edisi Pro. Perilaku build sepenuhnya diatur oleh AstBuildOptions.
Permukaan API publik
Bagian berjudul “Permukaan API publik”| Symbol | Parameter | Perilaku default | Mengembalikan | Melempar atau gagal dengan | Catatan |
|---|---|---|---|---|---|
AstBuilder::__construct | PdfReader $reader, AstBuildOptions $options, ?AstCache $cache = null | Mengikat reader yang telah dimuat ke opsi build; caching bersifat opsional | AstBuilder | — | Cache null berarti setiap panggilan build() membangun ulang. |
AstBuilder::build | string $sourceHash (SHA-256 hex penuh dari byte PDF) | Pencarian cache, penolakan enkripsi, jalur structure-tree, fallback untagged, penyematan bounding-box, penyimpanan cache | AstDocument | AstUnsupportedEncryptionException, AstBuildLimitException, AstBuildTimeoutException | Cache hit mengembalikan tanpa mem-parse ulang. |
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 | Objek nilai konfigurasi immutable | AstBuildOptions | — | estimatedTokenBudget adalah petunjuk informatif; tidak diberlakukan. |
AstBuildOptions::pageRangeContains | int $pageIndex | True bila indeks berbasis-0 berada di dalam rentang yang dikonfigurasi | bool | — | Batas null bersifat terbuka; keduanya null berarti semua halaman. |
AstBuildOptions::hash | — | SHA-256 stabil atas semua nilai opsi | string | — | Nilai yang setara menghasilkan hash yang setara antar-instance; digunakan sebagai segmen cache-key. |
AstCache::__construct | CacheInterface $backend | Membungkus backend PSR-16 apa pun | AstCache | — | — |
AstCache::buildKey | string $sourceHash, AstBuildOptions $options | Key = nextpdf_ast_v1_ + 32 hex pertama dari source hash + _ + 16 hex pertama dari options hash | string | — | Perubahan opsi otomatis membatalkan hasil ter-cache. |
AstCache::get | string $cacheKey | Men-decode payload JSON melalui validasi per-field yang ketat | ?AstDocument | Tidak pernah melempar; kegagalan mengembalikan null | Payload yang rusak atau dirusak gagal secara tertutup sebagai cache miss. |
AstCache::set | string $cacheKey, AstDocument $document | Menyimpan JSON dengan TTL 24 jam, lalu memverifikasi dengan read-back segera | void | AstWriteVerificationException (namespace Exception) | Kegagalan write backend atau round-trip yang gagal akan memunculkan pengecualian. |
AstCache::delete | string $cacheKey | Penghapusan best-effort | void | Tidak pernah melempar | Kegagalan penghapusan backend ditelan. |
AstCache::has | string $cacheKey | Pemeriksaan keberadaan best-effort | bool | Tidak pernah melempar; kegagalan mengembalikan false | — |
AstMutator::updateNode | AstDocument $document, string $nodeId, array $updates | Mengganti text_content, mencatat entri Updated | AstDocument (instance baru) | InvalidArgumentException | Hanya key text_content yang diterapkan; key yang tidak dikenal diabaikan. |
AstMutator::deleteNode | AstDocument $document, string $nodeId | Menghapus node dari pohon in-memory, mencatat entri Deleted | AstDocument (instance baru) | InvalidArgumentException | Hanya penghapusan in-memory; lihat catatan redaksi di bawah. |
AstMutator::getMutationLog | — | Mengembalikan instance log yang dibagikan | MutationLog | — | Teruskan log yang sama ke AstWriter. |
AstMutator::resetLog | — | Membuang semua mutasi yang tercatat | void | — | Memulai log yang baru. |
MutationLog | record, all, isEmpty, count, forNode, mutatedNodeIds | Log in-memory append-only, urutan penyisipan dipertahankan | per metode | — | forNode mengembalikan entri terbaru untuk sebuah node; entri terakhir yang menang. |
MutationEntry::__construct | string $nodeId, MutationType $type, ?AstNode $originalNode, ?AstNode $mutatedNode, DateTimeImmutable $timestamp | Rekaman immutable dari satu mutasi | MutationEntry | — | originalNode bernilai null untuk Inserted; mutatedNode bernilai null untuk Deleted. |
MutationType | case enum Updated, Inserted, Deleted | Klasifikasi berbasis-string | — | — | Deleted di bawah OVERLAY menyembunyikan konten; tidak menghapus byte. |
AstWriter::write | string $originalPdfBytes, MutationLog $log | Menambahkan pembaruan inkremental yang stream overlay-nya menutupi bounding box yang dimutasi | string (byte PDF yang dimodifikasi) | AstWriteException | Log kosong mengembalikan input tanpa perubahan. Entri Inserted dan entri tanpa bounding box dilewati. |
AstWriter::writeAndVerify | string $originalPdfBytes, MutationLog $log | Menjalankan write(), lalu pemeriksaan struktural pada output | string (byte PDF terverifikasi) | AstWriteException, AstWriteVerificationException (namespace Writer) | Verifikasi bersifat struktural, bukan semantik. |
AstPdfEmitter::emit | AstNode $root, BinaryBuffer $buffer, ObjectRegistry $registry, array $pageObjects | Menulis StructTreeRoot, rantai StructElem, dan ParentTree untuk pohon yang diberikan | EmitResult | AstEmitException | Root harus berupa node Document dengan children. Emitter round-trip untuk verifikasi structure-tree. |
EmitResult::__construct | int $structTreeRootObject, int $rootElementObject, int $parentTreeObject, int $elementObjectCount, int $parentTreeNextKey | Rekaman immutable dari identifier objek yang dipancarkan | 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): stringHierarki pengecualian
Bagian berjudul “Hierarki pengecualian”NextPDF\Pro\Ast\Exception\AstExceptionextendsRuntimeException— basis dari hierarki build.AstBuildLimitExceptionextendsAstException— batas atas node, depth, atau memory terlampaui.AstBuildTimeoutExceptionextendsAstBuildLimitException— timeout build wall-clock terlewati.AstNoStructTreeExceptionextendsAstException— tidak ada structure tree.AstBuilder::build()menangkapnya secara internal dan melakukan fallback; pemanggilbuild()tidak mengamatinya.AstUnsupportedEncryptionExceptionextendsAstException— PDF input terenkripsi.NextPDF\Pro\Ast\Exception\AstWriteVerificationExceptionextendsAstException— verifikasi write cache gagal.NextPDF\Pro\Ast\Writer\AstWriteExceptionextendsRuntimeException— kegagalan input atau struktur writer.NextPDF\Pro\Ast\Writer\AstWriteVerificationExceptionextendsAstWriteException— verifikasi struktural pasca-write gagal.
Terdapat dua kelas AstWriteVerificationException yang berbeda di namespace yang berbeda. AstCache::set() memunculkan kelas dari namespace Exception; AstWriter::writeAndVerify() memunculkan kelas dari namespace Writer. Sesuaikan namespace dalam klausa catch.
Kontrak perilaku
Bagian berjudul “Kontrak perilaku”AstBuilder::build($sourceHash) memerlukan SHA-256 hex penuh dari byte sumber. Pipeline-nya adalah: pencarian cache opsional, penolakan enkripsi, jalur structure-tree, fallback untagged, penyematan bounding-box, penyimpanan cache opsional.
Cache key menggabungkan source hash dengan hash AstBuildOptions. Hash opsi stabil antar-instance dengan nilai yang identik, sehingga input dan opsi yang identik mengembalikan pohon yang sama. Ketika tidak ada cache yang disediakan, setiap panggilan membangun ulang. Payload ter-cache berupa JSON, tidak pernah serialisasi native PHP: jalur baca memvalidasi setiap field dan hanya meng-instantiate tipe nilai AST, sehingga entri cache yang diracuni tidak dapat memicu object injection dan menurun menjadi cache miss.
Jalur structure-tree berjalan ketika structure tree hadir. Batas atas sumber daya — jumlah node, depth, delta memory, dan waktu wall-clock — diberlakukan selama pembacaan structure-tree dan memunculkan AstBuildLimitException atau AstBuildTimeoutException. Jika reader melaporkan tidak ada structure tree, builder beralih ke jalur untagged: builder heuristik ketika useHeuristic bernilai true, jika tidak maka builder fallback polos. Bounding box disematkan dengan menganalisis content stream dari setiap halaman yang berada dalam rentang; sebuah halaman yang content stream-nya tidak dapat di-parse akan dilewati dan membiarkan sisa pohon tetap utuh.
AstNode bersifat immutable. Pembaruan pohon membangun ulang node yang terdampak secara bottom-up; subtree yang tidak berubah dikembalikan berdasarkan identity. AstMutator mengikuti kontrak yang sama: setiap mutasi mengembalikan AstDocument baru, hanya membangun ulang jalur root-ke-target, dan mencatat sebuah MutationEntry dalam MutationLog yang dibagikan.
AstWriter menerapkan MutationLog dalam mode OVERLAY sebagai pembaruan inkremental append-only: content stream overlay baru, objek halaman yang diperbarui, sebuah bagian cross-reference yang hanya menutupi objek baru, dan sebuah trailer yang /Prev-nya menunjuk ke startxref sebelumnya. Byte asli dibiarkan utuh, sesuai model pembaruan inkremental dari ISO 32000-2:2020, 7.5.6. Teks pengganti yang digambar untuk entri Updated meng-escape \, (, dan ) dalam literal string, sesuai ISO 32000-2:2020, 7.3.4.2.
AstPdfEmitter::emit() adalah invers simetris dari pembacaan structure-tree: pohon yang diproduksi oleh reader melakukan round-trip menjadi pohon yang setara secara struktural, dengan pengecualian penomoran-ulang node-id dan kelas kanonikalisasi yang terdokumentasi. MCID yang hadir pada node dipancarkan ulang secara verbatim, tidak pernah dialokasikan ulang.
Kasus tepi & mode kegagalan
Bagian berjudul “Kasus tepi & mode kegagalan”- Input terenkripsi ditolak sebelum pekerjaan pohon apa pun; tidak ada hasil pohon parsial untuk PDF terenkripsi. Dekripsi terlebih dahulu.
- Batas atas sumber daya: max node (default 100.000), max depth (default 200), max memory (default 256 MiB), timeout wall-clock (default 30 d). Melampaui suatu batas atas memunculkan
AstBuildLimitException; timeout memunculkanAstBuildTimeoutException, sebuah subclass. - Rentang halaman bersifat berbasis-0 dan inklusif; batas null berarti semua halaman.
- Sebuah halaman yang content stream-nya tidak dapat di-parse akan dilewati selama penyematan bounding-box; sisa pohon tidak terpengaruh.
AstCache::get()tidak pernah melempar: payload yang rusak, dirusak, atau bukan-string mengembalikan null dan memaksa build ulang.AstCache::set()gagal dengan lantang ketika write backend atau read-back segera gagal.AstMutatormemunculkanInvalidArgumentExceptionketika node id tidak ditemukan. Key update yang tidak dikenal diabaikan secara diam-diam; hanyatext_contentyang diterapkan.AstWriter::write()memunculkanAstWriteExceptionketika input tidak memiliki header%PDF-ataustartxrefyang dapat dilokasikan. Entri tanpa bounding box dilewati secara diam-diam. Halaman yang tidak dapat dilokasikan melalui object scan — misalnya di bawah cross-reference stream terkompresi — akan dilewati; jika tidak ada overlay yang dapat diterapkan, byte input dikembalikan tanpa perubahan.- Output OVERLAY bukanlah redaksi. Persegi panjang putih dan teks yang digambar ulang ditambahkan; byte konten asli tetap ada dalam file dan dapat dipulihkan melalui ekstraksi mentah. Jangan gunakan untuk penghapusan GDPR Art. 17 atau redaksi legal. Sebuah writer mode reconstruct ada dalam source tree tetapi ditandai internal, belum production-ready, dan berada di luar permukaan API yang didukung.
- Geometri overlay mengasumsikan A4 portrait (595 x 842 pt) karena writer tidak membaca MediaBox halaman. Pada halaman non-A4 overlay mungkin sedikit tidak sejajar; output tetap valid secara struktural.
writeAndVerify()hanya memeriksa struktur: header,%%EOFdi akhir, dan pertumbuhan output. Ia tidak mem-parse ulang dokumen yang dimutasi secara semantik.AstPdfEmitter::emit()memunculkanAstEmitExceptionketika root bukan node Document atau tidak memiliki children. Entri pendamping OBJR (anotasi) tidak dipancarkan dalam rilis ini.- Modul ini tidak melakukan operasi kriptografis dan tidak mendefinisikan perilaku spesifik-FIPS. SHA-256 hanya muncul sebagai content addressing untuk cache key.
Konformitas
Bagian berjudul “Konformitas”Jalur structure-tree membaca fasilitas struktur logis tagged-PDF yang didefinisikan oleh ISO 32000-2; korpus RAG yang tersedia pada saat penulisan tidak mencakup klausa struktur-logis, sehingga pernyataan tersebut bersumber dari produk berdasarkan anotasi sumber. Tata letak pembaruan inkremental writer mengikuti ISO 32000-2:2020, 7.5.6 (dikutip di bawah), dan escaping literal string-nya mengikuti ISO 32000-2:2020, 7.3.4.2 (dikutip di bawah).
Pernyataan-pernyataan ini mendeskripsikan kapabilitas terhadap klausa yang dikutip. NextPDF tidak memegang sertifikasi konformitas apa pun, dan dukungan terhadap suatu klausa bukanlah klaim sertifikasi.
Catatan pengembangan
Bagian berjudul “Catatan pengembangan”- Susun satu
AstBuilderperPdfReaderyang dimuat. Gunakan ulang sebuahAstCachelintas build untuk mengamortisasi parsing; desain key membuat perubahan opsi membatalkan dirinya sendiri. - Bagikan satu
MutationLogantaraAstMutatordanAstWriteragar writer menerapkan tepat sesi yang tercatat. PanggilresetLog()di antara sesi penyuntingan yang independen. - Set
useHeuristicke true untuk dokumen untagged ketika pengelompokan berbasis-layout lebih disukai daripada pohon fallback polos. - Build bersifat deterministik untuk byte dan opsi yang identik; andalkan ini untuk pengujian bergaya snapshot.
- Tangkap kegagalan build melalui hierarki
NextPDF\Pro\Ast\Exceptiondan kegagalan write melalui hierarkiNextPDF\Pro\Ast\Writer; keduanya tidak berbagi basis di bawahRuntimeException.
Batas publikasi
Bagian berjudul “Batas publikasi”Halaman ini hanya mendokumentasikan perilaku yang dapat diamati secara eksternal dan permukaan API publik yang didukung. Jalur namespace internal, kelas helper, tabel mekanisme, nama file runbook, dan prefiks tiket berada di luar cakupan.