Pro phiên bản
AST — Tài liệu tham chiếu chuyên sâu
Tổng quan nhanh
Phần tiêu đề “Tổng quan nhanh”Trang này là tài liệu tham chiếu chuyên sâu cho module AST của Pro. Nó bao gồm các bề mặt build, cache, mutation, write và emit công khai, các hợp đồng hành vi của chúng, và các chế độ lỗi. Module phân tích một PDF đã tải thành một cây AstDocument bất biến, áp dụng các mutation trong bộ nhớ có ghi log, và ghi các cập nhật gia tăng dựa trên overlay. AstDocument và AstNode là các kiểu giá trị Core trong namespace NextPDF\Ast; module này tạo ra và tiêu thụ chúng.
Khả dụng & cấp phép
Phần tiêu đề “Khả dụng & cấp phép”Năng lực này đi kèm trong NextPDF Pro (nextpdf/pro) và kích hoạt với một envelope giấy phép bậc Pro. Một triển khai không có quyền đó sẽ không tải các lớp của năng lực. So sánh các phiên bản và lấy giấy phép.
Không tồn tại cờ giấy phép theo từng tính năng. Đây là một năng lực của phiên bản Pro. Hành vi dựng được điều chỉnh hoàn toàn bởi AstBuildOptions.
Bề mặt Public API
Phần tiêu đề “Bề mặt Public API”| Ký hiệu | Tham số | Hành vi mặc định | Trả về | Ném ra hoặc thất bại với | Ghi chú |
|---|---|---|---|---|---|
AstBuilder::__construct | PdfReader $reader, AstBuildOptions $options, ?AstCache $cache = null | Gắn một reader đã tải vào các tùy chọn dựng; cache là tùy chọn | AstBuilder | — | Cache null nghĩa là mọi lời gọi build() đều dựng lại. |
AstBuilder::build | string $sourceHash (chuỗi hex SHA-256 đầy đủ của các byte PDF) | Tra cứu cache, từ chối mã hóa, đường dẫn structure-tree, dự phòng untagged, gắn kèm bounding-box, lưu cache | AstDocument | AstUnsupportedEncryptionException, AstBuildLimitException, AstBuildTimeoutException | Một lần trúng cache trả về mà không phân tích lại. |
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 | Đối tượng giá trị cấu hình bất biến | AstBuildOptions | — | estimatedTokenBudget là một gợi ý mang tính thông tin; nó không được thực thi. |
AstBuildOptions::pageRangeContains | int $pageIndex | True khi chỉ số đánh số từ 0 nằm trong phạm vi đã cấu hình | bool | — | Các biên null là mở; cả hai null nghĩa là tất cả các trang. |
AstBuildOptions::hash | — | SHA-256 ổn định trên tất cả các giá trị tùy chọn | string | — | Các giá trị bằng nhau cho ra hash bằng nhau trên các thực thể; dùng làm phân đoạn khóa cache. |
AstCache::__construct | CacheInterface $backend | Bọc bất kỳ backend PSR-16 nào | AstCache | — | — |
AstCache::buildKey | string $sourceHash, AstBuildOptions $options | Khóa = nextpdf_ast_v1_ + 32 hex đầu của source hash + _ + 16 hex đầu của options hash | string | — | Thay đổi tùy chọn tự động vô hiệu hóa các kết quả đã cache. |
AstCache::get | string $cacheKey | Giải mã một payload JSON qua kiểm tra chặt chẽ theo từng trường | ?AstDocument | Không bao giờ ném; các thất bại trả về null | Các payload dị dạng hoặc bị giả mạo thất bại đóng (fail closed) như một lần trượt cache. |
AstCache::set | string $cacheKey, AstDocument $document | Lưu JSON với TTL 24 giờ, rồi xác minh bằng cách đọc lại ngay lập tức | void | AstWriteVerificationException (namespace Exception) | Thất bại ghi backend hoặc một vòng khứ hồi thất bại sẽ phát sinh lỗi. |
AstCache::delete | string $cacheKey | Xóa theo kiểu cố-gắng-tối-đa (best-effort) | void | Không bao giờ ném | Các thất bại xóa của backend bị nuốt. |
AstCache::has | string $cacheKey | Kiểm tra tồn tại theo kiểu cố-gắng-tối-đa | bool | Không bao giờ ném; các thất bại trả về false | — |
AstMutator::updateNode | AstDocument $document, string $nodeId, array $updates | Thay thế text_content, ghi lại một mục Updated | AstDocument (thực thể mới) | InvalidArgumentException | Chỉ khóa text_content được áp dụng; các khóa không rõ bị bỏ qua. |
AstMutator::deleteNode | AstDocument $document, string $nodeId | Loại node khỏi cây trong bộ nhớ, ghi lại một mục Deleted | AstDocument (thực thể mới) | InvalidArgumentException | Chỉ loại trong bộ nhớ; xem lưu ý về redaction bên dưới. |
AstMutator::getMutationLog | — | Trả về thực thể log dùng chung | MutationLog | — | Truyền cùng log đó cho AstWriter. |
AstMutator::resetLog | — | Loại bỏ tất cả các mutation đã ghi | void | — | Bắt đầu một log mới. |
MutationLog | record, all, isEmpty, count, forNode, mutatedNodeIds | Log trong bộ nhớ chỉ-thêm (append-only), giữ nguyên thứ tự chèn | theo từng phương thức | — | forNode trả về mục gần nhất cho một node; mục cuối thắng. |
MutationEntry::__construct | string $nodeId, MutationType $type, ?AstNode $originalNode, ?AstNode $mutatedNode, DateTimeImmutable $timestamp | Bản ghi bất biến của một mutation | MutationEntry | — | originalNode là null với Inserted; mutatedNode là null với Deleted. |
MutationType | các case enum Updated, Inserted, Deleted | Phân loại được hậu thuẫn bởi chuỗi (string-backed) | — | — | Deleted dưới OVERLAY ẩn nội dung; nó không xóa byte. |
AstWriter::write | string $originalPdfBytes, MutationLog $log | Nối thêm một cập nhật gia tăng có các overlay stream phủ các bounding box đã mutate | string (byte PDF đã sửa) | AstWriteException | Một log rỗng trả về đầu vào không đổi. Các mục Inserted và các mục không có bounding box bị bỏ qua. |
AstWriter::writeAndVerify | string $originalPdfBytes, MutationLog $log | Chạy write(), rồi một kiểm tra đầu ra về cấu trúc | string (byte PDF đã xác minh) | AstWriteException, AstWriteVerificationException (namespace Writer) | Xác minh mang tính cấu trúc, không phải ngữ nghĩa. |
AstPdfEmitter::emit | AstNode $root, BinaryBuffer $buffer, ObjectRegistry $registry, array $pageObjects | Ghi một StructTreeRoot, chuỗi StructElem, và ParentTree cho cây được cung cấp | EmitResult | AstEmitException | Root phải là một node Document có các node con. Emitter khứ hồi để xác minh structure-tree. |
EmitResult::__construct | int $structTreeRootObject, int $rootElementObject, int $parentTreeObject, int $elementObjectCount, int $parentTreeNextKey | Bản ghi bất biến của các định danh đối tượng đã phát ra | 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): stringHệ phân cấp ngoại lệ
Phần tiêu đề “Hệ phân cấp ngoại lệ”NextPDF\Pro\Ast\Exception\AstExceptionextendsRuntimeException— cơ sở của hệ phân cấp build.AstBuildLimitExceptionextendsAstException— đã vượt một trần về node, độ sâu, hoặc bộ nhớ.AstBuildTimeoutExceptionextendsAstBuildLimitException— timeout dựng theo thời gian thực-tế đã hết.AstNoStructTreeExceptionextendsAstException— không có structure tree hiện diện.AstBuilder::build()bắt nó nội bộ và dự phòng; các lời gọi tớibuild()không quan sát thấy nó.AstUnsupportedEncryptionExceptionextendsAstException— PDF đầu vào đã được mã hóa.NextPDF\Pro\Ast\Exception\AstWriteVerificationExceptionextendsAstException— xác minh ghi cache thất bại.NextPDF\Pro\Ast\Writer\AstWriteExceptionextendsRuntimeException— lỗi đầu vào hoặc cấu trúc của writer.NextPDF\Pro\Ast\Writer\AstWriteVerificationExceptionextendsAstWriteException— xác minh cấu trúc sau khi ghi thất bại.
Tồn tại hai lớp AstWriteVerificationException khác biệt trong các namespace khác nhau. AstCache::set() phát ra lớp thuộc namespace Exception; AstWriter::writeAndVerify() phát ra lớp thuộc namespace Writer. Hãy khớp namespace trong các mệnh đề catch.
Hợp đồng hành vi
Phần tiêu đề “Hợp đồng hành vi”AstBuilder::build($sourceHash) yêu cầu chuỗi hex SHA-256 đầy đủ của các byte nguồn. Pipeline là: tra cứu cache tùy chọn, từ chối mã hóa, đường dẫn structure-tree, dự phòng untagged, gắn kèm bounding-box, lưu cache tùy chọn.
Khóa cache kết hợp source hash với hash của AstBuildOptions. Hash của các tùy chọn ổn định trên các thực thể có giá trị giống hệt, nên các đầu vào và tùy chọn giống hệt sẽ trả về cùng một cây. Khi không cung cấp cache, mọi lời gọi đều dựng lại. Các payload đã cache là JSON, không bao giờ là serialization gốc của PHP: đường dẫn đọc kiểm tra từng trường và chỉ khởi tạo các kiểu giá trị AST, nên một mục cache bị đầu độc không thể kích hoạt object injection và suy giảm thành một lần trượt cache.
Đường dẫn structure-tree chạy khi có một structure tree hiện diện. Các trần tài nguyên — số node, độ sâu, delta bộ nhớ, và thời gian thực-tế — được thực thi trong lúc đọc structure-tree và phát sinh AstBuildLimitException hoặc AstBuildTimeoutException. Nếu trình đọc báo cáo không có structure tree, builder chuyển sang đường dẫn untagged: bộ dựng suy nghiệm khi useHeuristic là true, nếu không thì bộ dựng dự phòng trần. Các bounding box được gắn kèm bằng cách phân tích content stream của mỗi trang trong phạm vi; một trang có content stream không phân tích cú pháp được sẽ bị bỏ qua và giữ nguyên phần còn lại của cây.
AstNode là bất biến. Các cập nhật cây dựng lại các node bị ảnh hưởng theo hướng từ dưới lên; các cây con không thay đổi được trả về theo định danh (identity). AstMutator tuân theo cùng hợp đồng đó: mỗi mutation trả về một AstDocument mới, chỉ dựng lại đường từ root tới target, và ghi một MutationEntry vào MutationLog dùng chung.
AstWriter áp dụng một MutationLog ở chế độ OVERLAY như một cập nhật gia tăng chỉ-thêm: các content stream overlay mới, các đối tượng trang được cập nhật, một mục cross-reference chỉ phủ các đối tượng mới, và một trailer có /Prev trỏ tới startxref trước đó. Các byte gốc được giữ nguyên vẹn, theo mô hình cập nhật gia tăng của ISO 32000-2:2020, 7.5.6. Văn bản thay thế được vẽ cho các mục Updated sẽ escape \, (, và ) trong các literal string, theo ISO 32000-2:2020, 7.3.4.2.
AstPdfEmitter::emit() là nghịch đảo đối xứng của việc đọc structure-tree: các cây do trình đọc tạo ra khứ hồi thành các cây tương đương về cấu trúc, sai khác ở việc đánh số lại node-id và các lớp canonical hóa đã ghi tài liệu. Các MCID hiện diện trên các node được phát lại nguyên văn, không bao giờ được cấp phát lại.
Trường hợp biên & các chế độ lỗi
Phần tiêu đề “Trường hợp biên & các chế độ lỗi”- Đầu vào đã mã hóa bị từ chối trước bất kỳ công việc cây nào; không có kết quả cây-một-phần cho các PDF đã mã hóa. Hãy giải mã trước.
- Trần tài nguyên: số node tối đa (mặc định 100,000), độ sâu tối đa (mặc định 200), bộ nhớ tối đa (mặc định 256 MiB), timeout thời gian thực-tế (mặc định 30 s). Vượt quá một trần sẽ phát sinh
AstBuildLimitException; timeout phát sinhAstBuildTimeoutException, một lớp con. - Phạm vi trang đánh số từ 0 và bao gồm cả hai đầu; các biên null nghĩa là tất cả các trang.
- Một trang có content stream không phân tích cú pháp được sẽ bị bỏ qua trong lúc gắn kèm bounding-box; phần còn lại của cây không bị ảnh hưởng.
AstCache::get()không bao giờ ném: các payload dị dạng, bị giả mạo, hoặc không phải chuỗi sẽ trả về null và buộc dựng lại.AstCache::set()thất bại một cách rõ ràng khi ghi backend hoặc đọc-lại ngay lập tức thất bại.AstMutatorphát sinhInvalidArgumentExceptionkhi không tìm thấy node id. Các khóa cập nhật không rõ bị âm thầm bỏ qua; chỉtext_contentđược áp dụng.AstWriter::write()phát sinhAstWriteExceptionkhi đầu vào thiếu header%PDF-hoặc mộtstartxrefđịnh vị được. Các mục không có bounding box bị âm thầm bỏ qua. Các trang không thể định vị bằng quét đối tượng — ví dụ dưới các cross-reference stream đã nén — bị bỏ qua; nếu không overlay nào áp dụng được, các byte đầu vào được trả về không đổi.- Đầu ra OVERLAY không phải là redaction. Hình chữ nhật trắng và văn bản vẽ lại được nối thêm; các byte nội dung gốc vẫn còn trong tệp và có thể khôi phục bằng trích xuất thô. Đừng dùng nó cho việc xóa theo GDPR Art. 17 hoặc redaction pháp lý. Một writer chế độ reconstruct tồn tại trong cây nguồn nhưng được đánh dấu nội bộ, chưa sẵn sàng cho production, và nằm ngoài bề mặt API được hỗ trợ.
- Hình học overlay giả định A4 dọc (595 x 842 pt) vì writer không đọc MediaBox của trang. Trên các trang không phải A4 overlay có thể lệch nhẹ; đầu ra vẫn hợp lệ về cấu trúc.
writeAndVerify()chỉ kiểm tra cấu trúc: header,%%EOFở cuối, và sự tăng trưởng đầu ra. Nó không phân tích lại tài liệu đã mutate theo ngữ nghĩa.AstPdfEmitter::emit()phát sinhAstEmitExceptionkhi root không phải là node Document hoặc không có node con. Các mục đồng hành OBJR (annotation) không được phát ra trong bản phát hành này.- Module này không thực hiện thao tác mật mã nào và không định nghĩa hành vi riêng cho FIPS. SHA-256 chỉ xuất hiện như một cách địa chỉ hóa theo nội dung cho các khóa cache.
Tính phù hợp
Phần tiêu đề “Tính phù hợp”Đường dẫn structure-tree đọc các phương tiện cấu trúc logic của tagged-PDF được định nghĩa bởi ISO 32000-2; corpus RAG khả dụng tại thời điểm soạn thảo không bao gồm các điều khoản cấu trúc logic, nên khẳng định đó được đặt nền trên sản phẩm từ các chú thích nguồn. Bố cục cập nhật gia tăng của writer tuân theo ISO 32000-2:2020, 7.5.6 (được trích dẫn bên dưới), và việc escape literal string của nó tuân theo ISO 32000-2:2020, 7.3.4.2 (được trích dẫn bên dưới).
Các khẳng định này mô tả năng lực đối chiếu với các điều khoản được trích dẫn. NextPDF không nắm giữ chứng nhận phù hợp nào, và việc hỗ trợ một điều khoản không phải là một tuyên bố chứng nhận.
Ghi chú phát triển
Phần tiêu đề “Ghi chú phát triển”- Soạn một
AstBuildercho mỗiPdfReaderđã tải. Tái dùng mộtAstCachequa các bản dựng để phân bổ chi phí phân tích; thiết kế khóa khiến các thay đổi tùy chọn tự vô hiệu hóa. - Chia sẻ một
MutationLoggiữa mộtAstMutatorvàAstWriterđể writer áp dụng đúng phiên đã ghi. GọiresetLog()giữa các phiên chỉnh sửa độc lập. - Đặt
useHeuristicthành true cho các tài liệu untagged khi việc gom nhóm dựa trên layout được ưa chuộng hơn cây dự phòng trần. - Các bản dựng có tính tất định với các byte và tùy chọn giống hệt; hãy dựa vào điều này cho các test kiểu snapshot.
- Bắt các thất bại dựng qua hệ phân cấp
NextPDF\Pro\Ast\Exceptionvà các thất bại ghi qua hệ phân cấpNextPDF\Pro\Ast\Writer; hai hệ này không chia sẻ một cơ sở nào dướiRuntimeException.
Ranh giới công bố
Phần tiêu đề “Ranh giới công bố”Trang này chỉ ghi tài liệu hành vi quan sát được từ bên ngoài và bề mặt public API được hỗ trợ. Các đường dẫn namespace nội bộ, các lớp trợ giúp, các bảng cơ chế, các tên tệp runbook, và các tiền tố ticket nằm ngoài phạm vi.