Pular para o conteúdo
getnextpdf.com

Pro edição

AST — Referência Profunda

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.

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.

SímboloParâmetrosComportamento padrãoRetornaLança ou falha comNotas
AstBuilder::__constructPdfReader $reader, AstBuildOptions $options, ?AstCache $cache = nullVincula um reader carregado às opções de build; o cache é opcionalAstBuilderUm cache nulo faz com que toda chamada build() reconstrua.
AstBuilder::buildstring $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 cacheAstDocumentAstUnsupportedEncryptionException, AstBuildLimitException, AstBuildTimeoutExceptionUm 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 = falseObjeto de valor de configuração imutávelAstBuildOptionsestimatedTokenBudget é uma dica informativa; não é imposto.
AstBuildOptions::pageRangeContainsint $pageIndexVerdadeiro quando o índice baseado em 0 cai dentro do intervalo configuradoboolLimites nulos são abertos; ambos nulos significam todas as páginas.
AstBuildOptions::hashSHA-256 estável sobre todos os valores de opçãostringValores iguais produzem hashes iguais entre instâncias; usado como o segmento da chave de cache.
AstCache::__constructCacheInterface $backendEncapsula qualquer backend PSR-16AstCache
AstCache::buildKeystring $sourceHash, AstBuildOptions $optionsChave = nextpdf_ast_v1_ + primeiros 32 hex do hash de origem + _ + primeiros 16 hex do hash de opçõesstringMudanças nas opções invalidam automaticamente os resultados em cache.
AstCache::getstring $cacheKeyDecodifica um payload JSON por meio de validação estrita campo a campo?AstDocumentNunca lança; falhas retornam nullPayloads malformados ou adulterados falham de forma fechada como um cache miss.
AstCache::setstring $cacheKey, AstDocument $documentArmazena JSON com um TTL de 24 horas, depois verifica por releitura imediatavoidAstWriteVerificationException (namespace Exception)Falha de escrita do backend ou uma ida-e-volta falha levanta.
AstCache::deletestring $cacheKeyRemoção de melhor esforçovoidNunca lançaFalhas de exclusão do backend são silenciadas.
AstCache::hasstring $cacheKeyVerificação de existência de melhor esforçoboolNunca lança; falhas retornam false
AstMutator::updateNodeAstDocument $document, string $nodeId, array $updatesSubstitui text_content, registra uma entrada UpdatedAstDocument (nova instância)InvalidArgumentExceptionApenas a chave text_content é aplicada; chaves desconhecidas são ignoradas.
AstMutator::deleteNodeAstDocument $document, string $nodeIdRemove o nó da árvore em memória, registra uma entrada DeletedAstDocument (nova instância)InvalidArgumentExceptionRemoção apenas em memória; veja a ressalva sobre redação abaixo.
AstMutator::getMutationLogRetorna a instância de log compartilhadaMutationLogPasse o mesmo log para o AstWriter.
AstMutator::resetLogDescarta todas as mutações registradasvoidInicia um novo log.
MutationLogrecord, all, isEmpty, count, forNode, mutatedNodeIdsLog em memória somente de acréscimo, ordem de inserção preservadapor métodoforNode retorna a entrada mais recente de um nó; a última entrada vence.
MutationEntry::__constructstring $nodeId, MutationType $type, ?AstNode $originalNode, ?AstNode $mutatedNode, DateTimeImmutable $timestampRegistro imutável de uma mutaçãoMutationEntryoriginalNode é null para Inserted; mutatedNode é null para Deleted.
MutationTypecasos de enum Updated, Inserted, DeletedClassificação baseada em stringDeleted sob OVERLAY oculta o conteúdo; não apaga bytes.
AstWriter::writestring $originalPdfBytes, MutationLog $logAcrescenta uma atualização incremental cujos fluxos de overlay cobrem as bounding boxes mutadasstring (bytes de PDF modificados)AstWriteExceptionUm log vazio retorna a entrada inalterada. Entradas Inserted e entradas sem bounding box são puladas.
AstWriter::writeAndVerifystring $originalPdfBytes, MutationLog $logExecuta write(), depois uma verificação estrutural da saídastring (bytes de PDF verificados)AstWriteException, AstWriteVerificationException (namespace Writer)A verificação é estrutural, não semântica.
AstPdfEmitter::emitAstNode $root, BinaryBuffer $buffer, ObjectRegistry $registry, array $pageObjectsEscreve um StructTreeRoot, uma cadeia StructElem e uma ParentTree para a árvore fornecidaEmitResultAstEmitExceptionA raiz deve ser um nó Document com filhos. Emitter de ida-e-volta para verificação da árvore de estrutura.
EmitResult::__constructint $structTreeRootObject, int $rootElementObject, int $parentTreeObject, int $elementObjectCount, int $parentTreeNextKeyRegistro imutável dos identificadores de objeto emitidosEmitResult
public function build(string $sourceHash): AstDocument
public function updateNode(AstDocument $document, string $nodeId, array $updates): AstDocument
public function deleteNode(AstDocument $document, string $nodeId): AstDocument
public function write(string $originalPdfBytes, MutationLog $log): string
public function writeAndVerify(string $originalPdfBytes, MutationLog $log): string
  • NextPDF\Pro\Ast\Exception\AstException estende RuntimeException — base da hierarquia de build.
  • AstBuildLimitException estende AstException — um teto de nós, profundidade ou memória foi excedido.
  • AstBuildTimeoutException estende AstBuildLimitException — o timeout de tempo de parede do build expirou.
  • AstNoStructTreeException estende AstException — nenhuma árvore de estrutura presente. AstBuilder::build() a captura internamente e faz fallback; chamadores de build() não a observam.
  • AstUnsupportedEncryptionException estende AstException — o PDF de entrada está criptografado.
  • NextPDF\Pro\Ast\Exception\AstWriteVerificationException estende AstException — a verificação de escrita do cache falhou.
  • NextPDF\Pro\Ast\Writer\AstWriteException estende RuntimeException — falha de entrada ou estrutura do writer.
  • NextPDF\Pro\Ast\Writer\AstWriteVerificationException estende AstWriteException — 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.

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.

  • 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 levanta AstBuildTimeoutException, 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.
  • AstMutator levanta InvalidArgumentException quando o id do nó não é encontrado. Chaves de atualização desconhecidas são ignoradas silenciosamente; apenas text_content é aplicado.
  • AstWriter::write() levanta AstWriteException quando a entrada não tem um cabeçalho %PDF- ou um startxref localizá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, %%EOF final e crescimento da saída. Ela não reanalisa semanticamente o documento mutado.
  • AstPdfEmitter::emit() levanta AstEmitException quando 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.

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.

  • Componha um AstBuilder por PdfReader carregado. Reutilize um AstCache entre builds para amortizar a análise; o design da chave torna as mudanças de opções autoinvalidáveis.
  • Compartilhe um MutationLog entre um AstMutator e o AstWriter para que o writer aplique exatamente a sessão registrada. Chame resetLog() entre sessões de edição independentes.
  • Defina useHeuristic como 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\Exception e falhas de escrita por meio da hierarquia NextPDF\Pro\Ast\Writer; as duas não compartilham uma base abaixo de RuntimeException.

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.