Pro edição
AST — Referência Profunda
Visão geral
Seção intitulada “Visão geral”Esta página é a referência profunda do módulo AST do Pro. Ela cobre as superfícies públicas de build, cache, mutação, escrita e emissão, seus contratos de comportamento e seus modos de falha. O módulo analisa um PDF carregado em uma árvore AstDocument imutável, aplica mutações registradas em memória e escreve atualizações incrementais baseadas em overlay. AstDocument e AstNode são tipos de valor do Core no namespace NextPDF\Ast; este módulo os produz e consome.
Disponibilidade e licenciamento
Seção intitulada “Disponibilidade e licenciamento”Este recurso é distribuído no NextPDF Pro (nextpdf/pro) e é ativado com um envelope de licença de nível Pro. Uma implantação sem esse direito não carrega as classes do recurso. Compare edições e obtenha uma licença.
Não existe sinalizador de licença por recurso. Este é um recurso da edição Pro. O comportamento de build é governado inteiramente por AstBuildOptions.
Superfície pública da API
Seção intitulada “Superfície pública da API”| Símbolo | Parâmetros | Comportamento padrão | Retorna | Lança ou falha com | Notas |
|---|---|---|---|---|---|
AstBuilder::__construct | PdfReader $reader, AstBuildOptions $options, ?AstCache $cache = null | Vincula um reader carregado às opções de build; o cache é opcional | AstBuilder | — | Um cache nulo faz com que toda chamada build() reconstrua. |
AstBuilder::build | string $sourceHash (SHA-256 hexadecimal completo dos bytes do PDF) | Busca em cache, rejeição de criptografia, caminho da árvore de estrutura, fallback não marcado, anexação de bounding box, armazenamento em cache | AstDocument | AstUnsupportedEncryptionException, AstBuildLimitException, AstBuildTimeoutException | Um acerto de cache retorna sem reanalisar. |
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 | Objeto de valor de configuração imutável | AstBuildOptions | — | estimatedTokenBudget é uma dica informativa; não é imposto. |
AstBuildOptions::pageRangeContains | int $pageIndex | Verdadeiro quando o índice baseado em 0 cai dentro do intervalo configurado | bool | — | Limites nulos são abertos; ambos nulos significam todas as páginas. |
AstBuildOptions::hash | — | SHA-256 estável sobre todos os valores de opção | string | — | Valores iguais produzem hashes iguais entre instâncias; usado como o segmento da chave de cache. |
AstCache::__construct | CacheInterface $backend | Encapsula qualquer backend PSR-16 | AstCache | — | — |
AstCache::buildKey | string $sourceHash, AstBuildOptions $options | Chave = nextpdf_ast_v1_ + primeiros 32 hex do hash de origem + _ + primeiros 16 hex do hash de opções | string | — | Mudanças nas opções invalidam automaticamente os resultados em cache. |
AstCache::get | string $cacheKey | Decodifica um payload JSON por meio de validação estrita campo a campo | ?AstDocument | Nunca lança; falhas retornam null | Payloads malformados ou adulterados falham de forma fechada como um cache miss. |
AstCache::set | string $cacheKey, AstDocument $document | Armazena JSON com um TTL de 24 horas, depois verifica por releitura imediata | void | AstWriteVerificationException (namespace Exception) | Falha de escrita do backend ou uma ida-e-volta falha levanta. |
AstCache::delete | string $cacheKey | Remoção de melhor esforço | void | Nunca lança | Falhas de exclusão do backend são silenciadas. |
AstCache::has | string $cacheKey | Verificação de existência de melhor esforço | bool | Nunca lança; falhas retornam false | — |
AstMutator::updateNode | AstDocument $document, string $nodeId, array $updates | Substitui text_content, registra uma entrada Updated | AstDocument (nova instância) | InvalidArgumentException | Apenas a chave text_content é aplicada; chaves desconhecidas são ignoradas. |
AstMutator::deleteNode | AstDocument $document, string $nodeId | Remove o nó da árvore em memória, registra uma entrada Deleted | AstDocument (nova instância) | InvalidArgumentException | Remoção apenas em memória; veja a ressalva sobre redação abaixo. |
AstMutator::getMutationLog | — | Retorna a instância de log compartilhada | MutationLog | — | Passe o mesmo log para o AstWriter. |
AstMutator::resetLog | — | Descarta todas as mutações registradas | void | — | Inicia um novo log. |
MutationLog | record, all, isEmpty, count, forNode, mutatedNodeIds | Log em memória somente de acréscimo, ordem de inserção preservada | por método | — | forNode retorna a entrada mais recente de um nó; a última entrada vence. |
MutationEntry::__construct | string $nodeId, MutationType $type, ?AstNode $originalNode, ?AstNode $mutatedNode, DateTimeImmutable $timestamp | Registro imutável de uma mutação | MutationEntry | — | originalNode é null para Inserted; mutatedNode é null para Deleted. |
MutationType | casos de enum Updated, Inserted, Deleted | Classificação baseada em string | — | — | Deleted sob OVERLAY oculta o conteúdo; não apaga bytes. |
AstWriter::write | string $originalPdfBytes, MutationLog $log | Acrescenta uma atualização incremental cujos fluxos de overlay cobrem as bounding boxes mutadas | string (bytes de PDF modificados) | AstWriteException | Um log vazio retorna a entrada inalterada. Entradas Inserted e entradas sem bounding box são puladas. |
AstWriter::writeAndVerify | string $originalPdfBytes, MutationLog $log | Executa write(), depois uma verificação estrutural da saída | string (bytes de PDF verificados) | AstWriteException, AstWriteVerificationException (namespace Writer) | A verificação é estrutural, não semântica. |
AstPdfEmitter::emit | AstNode $root, BinaryBuffer $buffer, ObjectRegistry $registry, array $pageObjects | Escreve um StructTreeRoot, uma cadeia StructElem e uma ParentTree para a árvore fornecida | EmitResult | AstEmitException | A raiz deve ser um nó Document com filhos. Emitter de ida-e-volta para verificação da árvore de estrutura. |
EmitResult::__construct | int $structTreeRootObject, int $rootElementObject, int $parentTreeObject, int $elementObjectCount, int $parentTreeNextKey | Registro imutável dos identificadores de objeto emitidos | 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): stringHierarquia de exceções
Seção intitulada “Hierarquia de exceções”NextPDF\Pro\Ast\Exception\AstExceptionestendeRuntimeException— base da hierarquia de build.AstBuildLimitExceptionestendeAstException— um teto de nós, profundidade ou memória foi excedido.AstBuildTimeoutExceptionestendeAstBuildLimitException— o timeout de tempo de parede do build expirou.AstNoStructTreeExceptionestendeAstException— nenhuma árvore de estrutura presente.AstBuilder::build()a captura internamente e faz fallback; chamadores debuild()não a observam.AstUnsupportedEncryptionExceptionestendeAstException— o PDF de entrada está criptografado.NextPDF\Pro\Ast\Exception\AstWriteVerificationExceptionestendeAstException— a verificação de escrita do cache falhou.NextPDF\Pro\Ast\Writer\AstWriteExceptionestendeRuntimeException— falha de entrada ou estrutura do writer.NextPDF\Pro\Ast\Writer\AstWriteVerificationExceptionestendeAstWriteException— a verificação estrutural pós-escrita falhou.
Existem duas classes AstWriteVerificationException distintas em namespaces diferentes. AstCache::set() lança a classe do namespace Exception; AstWriter::writeAndVerify() lança a classe do namespace Writer. Corresponda o namespace nas cláusulas catch.
Contrato de comportamento
Seção intitulada “Contrato de comportamento”AstBuilder::build($sourceHash) requer o SHA-256 hexadecimal completo dos bytes de origem. O pipeline é: busca opcional em cache, rejeição de criptografia, caminho da árvore de estrutura, fallback não marcado, anexação de bounding box, armazenamento opcional em cache.
A chave de cache combina o hash de origem com o hash de AstBuildOptions. O hash das opções é estável entre instâncias com valores idênticos, então entradas e opções idênticas retornam a mesma árvore. Quando nenhum cache é fornecido, toda chamada reconstrói. Os payloads em cache são JSON, nunca serialização nativa do PHP: o caminho de leitura valida cada campo e instancia apenas tipos de valor do AST, de modo que uma entrada de cache envenenada não pode disparar injeção de objeto e degrada para um cache miss.
O caminho da árvore de estrutura é executado quando uma árvore de estrutura está presente. Os tetos de recursos — contagem de nós, profundidade, delta de memória e tempo de parede — são impostos durante a leitura da árvore de estrutura e levantam AstBuildLimitException ou AstBuildTimeoutException. Se o leitor relatar que não há árvore de estrutura, o builder muda para o caminho não marcado: o builder heurístico quando useHeuristic é verdadeiro, caso contrário o builder de fallback simples. As bounding boxes são anexadas analisando o fluxo de conteúdo de cada página dentro do intervalo; uma página cujo fluxo de conteúdo não pode ser analisado é pulada e deixa o restante da árvore intacto.
AstNode é imutável. As atualizações da árvore reconstroem os nós afetados de baixo para cima; subárvores inalteradas são retornadas por identidade. AstMutator segue o mesmo contrato: cada mutação retorna um novo AstDocument, reconstrói apenas o caminho da raiz até o alvo e registra uma MutationEntry no MutationLog compartilhado.
AstWriter aplica um MutationLog no modo OVERLAY como uma atualização incremental somente de acréscimo: novos fluxos de conteúdo de overlay, objetos de página atualizados, uma seção de referência cruzada cobrindo apenas os novos objetos e um trailer cujo /Prev aponta para o startxref anterior. Os bytes originais são mantidos intactos, conforme o modelo de atualização incremental da ISO 32000-2:2020, 7.5.6. O texto de substituição desenhado para entradas Updated escapa \, ( e ) em strings literais, conforme a ISO 32000-2:2020, 7.3.4.2.
AstPdfEmitter::emit() é o inverso simétrico da leitura da árvore de estrutura: árvores produzidas pelo leitor fazem ida-e-volta para árvores estruturalmente equivalentes, a menos da renumeração de node-id e das classes de canonicalização documentadas. Os MCIDs presentes nos nós são reemitidos literalmente, nunca realocados.
Casos extremos e modos de falha
Seção intitulada “Casos extremos e modos de falha”- A entrada criptografada é rejeitada antes de qualquer trabalho de árvore; não há resultado de árvore parcial para PDFs criptografados. Descriptografe primeiro.
- Tetos de recursos: máximo de nós (padrão 100,000), profundidade máxima (padrão 200), memória máxima (padrão 256 MiB), timeout de tempo de parede (padrão 30 s). Exceder um teto levanta
AstBuildLimitException; o timeout levantaAstBuildTimeoutException, uma subclasse. - O intervalo de páginas é baseado em 0 e inclusivo; limites nulos significam todas as páginas.
- Uma página cujo fluxo de conteúdo não pode ser analisado é pulada durante a anexação de bounding box; o restante da árvore não é afetado.
AstCache::get()nunca lança: payloads malformados, adulterados ou não-string retornam null e forçam uma reconstrução.AstCache::set()falha de forma explícita quando a escrita do backend ou a releitura imediata falha.AstMutatorlevantaInvalidArgumentExceptionquando o id do nó não é encontrado. Chaves de atualização desconhecidas são ignoradas silenciosamente; apenastext_contenté aplicado.AstWriter::write()levantaAstWriteExceptionquando a entrada não tem um cabeçalho%PDF-ou umstartxreflocalizável. Entradas sem bounding box são puladas silenciosamente. Páginas que não podem ser localizadas por varredura de objetos — por exemplo, sob fluxos de referência cruzada comprimidos — são puladas; se nenhum overlay puder ser aplicado, os bytes de entrada são retornados inalterados.- A saída OVERLAY não é redação. O retângulo branco e o texto redesenhado são acrescentados; os bytes de conteúdo originais permanecem no arquivo e são recuperáveis por extração bruta. Não a use para apagamento do Art. 17 do GDPR nem para redação legal. Existe um writer em modo de reconstrução na árvore de código-fonte, mas ele é marcado como interno, não está pronto para produção e está fora da superfície de API suportada.
- A geometria do overlay assume A4 retrato (595 x 842 pt) porque o writer não lê o MediaBox da página. Em páginas não-A4 o overlay pode ficar levemente desalinhado; a saída permanece estruturalmente válida.
writeAndVerify()verifica apenas a estrutura: cabeçalho,%%EOFfinal e crescimento da saída. Ela não reanalisa semanticamente o documento mutado.AstPdfEmitter::emit()levantaAstEmitExceptionquando a raiz não é um nó Document ou não tem filhos. Entradas complementares OBJR (de anotação) não são emitidas nesta versão.- Este módulo não realiza operações criptográficas e não define comportamento específico de FIPS. O SHA-256 aparece apenas como endereçamento de conteúdo para chaves de cache.
Conformidade
Seção intitulada “Conformidade”O caminho da árvore de estrutura lê os recursos de estrutura lógica de PDF marcado definidos pela ISO 32000-2; o corpus de RAG disponível no momento da autoria não inclui as cláusulas de estrutura lógica, então essa afirmação é fundamentada no produto a partir das anotações da fonte. O layout de atualização incremental do writer segue a ISO 32000-2:2020, 7.5.6 (citada abaixo), e o escape de strings literais segue a ISO 32000-2:2020, 7.3.4.2 (citada abaixo).
Essas afirmações descrevem a capacidade em relação às cláusulas citadas. A NextPDF não possui certificação de conformidade, e o suporte a uma cláusula não é uma alegação de certificação.
Notas de desenvolvimento
Seção intitulada “Notas de desenvolvimento”- Componha um
AstBuilderporPdfReadercarregado. Reutilize umAstCacheentre builds para amortizar a análise; o design da chave torna as mudanças de opções autoinvalidáveis. - Compartilhe um
MutationLogentre umAstMutatore oAstWriterpara que o writer aplique exatamente a sessão registrada. ChameresetLog()entre sessões de edição independentes. - Defina
useHeuristiccomo verdadeiro para documentos não marcados quando o agrupamento derivado do layout for preferível à árvore de fallback simples. - Os builds são determinísticos para bytes e opções idênticos; conte com isso para testes no estilo snapshot.
- Capture falhas de build por meio da hierarquia
NextPDF\Pro\Ast\Exceptione falhas de escrita por meio da hierarquiaNextPDF\Pro\Ast\Writer; as duas não compartilham uma base abaixo deRuntimeException.
Limite de publicação
Seção intitulada “Limite de publicação”Esta página documenta apenas o comportamento observável externamente e a superfície pública de API suportada. Caminhos de namespace internos, classes auxiliares, tabelas de mecanismos, nomes de arquivos de runbook e prefixos de tíquetes estão fora do escopo.