Pro edición
AST — Referencia detallada
De un vistazo
Sección titulada «De un vistazo»Esta página es la referencia detallada del módulo AST de Pro. Cubre las superficies públicas de compilación, caché, mutación, escritura y emisión, sus contratos de comportamiento y sus modos de fallo. El módulo analiza un PDF cargado y lo convierte en un árbol inmutable AstDocument, aplica mutaciones en memoria registradas y escribe actualizaciones incrementales basadas en superposición. AstDocument y AstNode son tipos de valor de Core en el espacio de nombres NextPDF\Ast; este módulo los produce y los consume.
Disponibilidad y licencias
Sección titulada «Disponibilidad y licencias»Esta capacidad se distribuye en NextPDF Pro (nextpdf/pro) y se activa con un sobre de licencia de nivel Pro. Un despliegue sin ese derecho no carga las clases de la capacidad. Comparar ediciones y obtener una licencia.
No existe ningún indicador de licencia por función. Esta es una capacidad de la edición Pro. El comportamiento de compilación se rige por completo por AstBuildOptions.
Superficie de la API pública
Sección titulada «Superficie de la API pública»| Símbolo | Parámetros | Comportamiento predeterminado | Devuelve | Lanza o falla con | Notas |
|---|---|---|---|---|---|
AstBuilder::__construct | PdfReader $reader, AstBuildOptions $options, ?AstCache $cache = null | Vincula un lector cargado a las opciones de compilación; el uso de caché es opcional | AstBuilder | — | Una caché nula significa que cada llamada a build() recompila. |
AstBuilder::build | string $sourceHash (SHA-256 hexadecimal completo de los bytes del PDF) | Búsqueda en caché, rechazo de cifrado, ruta del árbol de estructura, alternativa sin etiquetar, adjunto de cuadros delimitadores, almacenamiento en caché | AstDocument | AstUnsupportedEncryptionException, AstBuildLimitException, AstBuildTimeoutException | Un acierto de caché devuelve sin volver a analizar. |
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 configuración inmutable | AstBuildOptions | — | estimatedTokenBudget es una pista informativa; no se aplica. |
AstBuildOptions::pageRangeContains | int $pageIndex | Verdadero cuando el índice basado en 0 cae dentro del rango configurado | bool | — | Los límites nulos son abiertos; ambos nulos significan todas las páginas. |
AstBuildOptions::hash | — | SHA-256 estable sobre todos los valores de las opciones | string | — | Valores iguales producen hashes iguales entre instancias; se usa como segmento de la clave de caché. |
AstCache::__construct | CacheInterface $backend | Envuelve cualquier backend PSR-16 | AstCache | — | — |
AstCache::buildKey | string $sourceHash, AstBuildOptions $options | Clave = nextpdf_ast_v1_ + primeros 32 hex del hash de origen + _ + primeros 16 hex del hash de opciones | string | — | Los cambios de opciones invalidan automáticamente los resultados en caché. |
AstCache::get | string $cacheKey | Decodifica una carga JSON mediante validación estricta campo por campo | ?AstDocument | Nunca lanza; los fallos devuelven null | Las cargas malformadas o manipuladas fallan de forma cerrada como un fallo de caché. |
AstCache::set | string $cacheKey, AstDocument $document | Almacena JSON con un TTL de 24 horas y luego verifica mediante relectura inmediata | void | AstWriteVerificationException (espacio de nombres Exception) | Un fallo de escritura del backend o un ciclo de ida y vuelta fallido lo provoca. |
AstCache::delete | string $cacheKey | Eliminación de mejor esfuerzo | void | Nunca lanza | Los fallos de eliminación del backend se descartan. |
AstCache::has | string $cacheKey | Comprobación de existencia de mejor esfuerzo | bool | Nunca lanza; los fallos devuelven false | — |
AstMutator::updateNode | AstDocument $document, string $nodeId, array $updates | Reemplaza text_content, registra una entrada Updated | AstDocument (nueva instancia) | InvalidArgumentException | Solo se aplica la clave text_content; las claves desconocidas se ignoran. |
AstMutator::deleteNode | AstDocument $document, string $nodeId | Elimina el nodo del árbol en memoria, registra una entrada Deleted | AstDocument (nueva instancia) | InvalidArgumentException | Solo eliminación en memoria; véase la advertencia sobre redacción más abajo. |
AstMutator::getMutationLog | — | Devuelve la instancia de registro compartida | MutationLog | — | Pasar el mismo registro a AstWriter. |
AstMutator::resetLog | — | Descarta todas las mutaciones registradas | void | — | Inicia un registro nuevo. |
MutationLog | record, all, isEmpty, count, forNode, mutatedNodeIds | Registro en memoria de solo anexado, con el orden de inserción preservado | por método | — | forNode devuelve la entrada más reciente de un nodo; gana la última entrada. |
MutationEntry::__construct | string $nodeId, MutationType $type, ?AstNode $originalNode, ?AstNode $mutatedNode, DateTimeImmutable $timestamp | Registro inmutable de una mutación | MutationEntry | — | originalNode es null para Inserted; mutatedNode es null para Deleted. |
MutationType | casos de enumeración Updated, Inserted, Deleted | Clasificación respaldada por cadena | — | — | Deleted bajo OVERLAY oculta el contenido; no borra bytes. |
AstWriter::write | string $originalPdfBytes, MutationLog $log | Anexa una actualización incremental cuyos flujos de superposición cubren los cuadros delimitadores mutados | string (bytes del PDF modificado) | AstWriteException | Un registro vacío devuelve la entrada sin cambios. Las entradas Inserted y las entradas sin cuadro delimitador se omiten. |
AstWriter::writeAndVerify | string $originalPdfBytes, MutationLog $log | Ejecuta write(), luego una comprobación estructural de la salida | string (bytes del PDF verificado) | AstWriteException, AstWriteVerificationException (espacio de nombres Writer) | La verificación es estructural, no semántica. |
AstPdfEmitter::emit | AstNode $root, BinaryBuffer $buffer, ObjectRegistry $registry, array $pageObjects | Escribe un StructTreeRoot, una cadena StructElem y un ParentTree para el árbol suministrado | EmitResult | AstEmitException | La raíz debe ser un nodo Document con hijos. Emisor de ida y vuelta para la verificación del árbol de estructura. |
EmitResult::__construct | int $structTreeRootObject, int $rootElementObject, int $parentTreeObject, int $elementObjectCount, int $parentTreeNextKey | Registro inmutable de los 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): stringJerarquía de excepciones
Sección titulada «Jerarquía de excepciones»NextPDF\Pro\Ast\Exception\AstExceptionextiendeRuntimeException— base de la jerarquía de compilación.AstBuildLimitExceptionextiendeAstException— se superó un techo de nodos, profundidad o memoria.AstBuildTimeoutExceptionextiendeAstBuildLimitException— transcurrió el tiempo de espera de compilación de reloj de pared.AstNoStructTreeExceptionextiendeAstException— no hay árbol de estructura presente.AstBuilder::build()la captura internamente y recurre a la alternativa; quienes llaman abuild()no la observan.AstUnsupportedEncryptionExceptionextiendeAstException— el PDF de entrada está cifrado.NextPDF\Pro\Ast\Exception\AstWriteVerificationExceptionextiendeAstException— falló la verificación de escritura en caché.NextPDF\Pro\Ast\Writer\AstWriteExceptionextiendeRuntimeException— fallo de entrada o estructura del escritor.NextPDF\Pro\Ast\Writer\AstWriteVerificationExceptionextiendeAstWriteException— falló la verificación estructural posterior a la escritura.
Existen dos clases AstWriteVerificationException distintas en espacios de nombres diferentes. AstCache::set() provoca la clase del espacio de nombres Exception; AstWriter::writeAndVerify() provoca la clase del espacio de nombres Writer. Hay que coincidir con el espacio de nombres en las cláusulas catch.
Contrato de comportamiento
Sección titulada «Contrato de comportamiento»AstBuilder::build($sourceHash) requiere el SHA-256 hexadecimal completo de los bytes de origen. La canalización es: búsqueda opcional en caché, rechazo de cifrado, ruta del árbol de estructura, alternativa sin etiquetar, adjunto de cuadros delimitadores y almacenamiento opcional en caché.
La clave de caché combina el hash de origen con el hash de AstBuildOptions. El hash de opciones es estable entre instancias con valores idénticos, de modo que entradas y opciones idénticas devuelven el mismo árbol. Cuando no se suministra ninguna caché, cada llamada recompila. Las cargas en caché son JSON, nunca serialización nativa de PHP: la ruta de lectura valida cada campo e instancia únicamente tipos de valor AST, por lo que una entrada de caché envenenada no puede desencadenar inyección de objetos y degrada a un fallo de caché.
La ruta del árbol de estructura se ejecuta cuando hay un árbol de estructura presente. Los techos de recursos —recuento de nodos, profundidad, delta de memoria y tiempo de reloj de pared— se aplican durante la lectura del árbol de estructura y provocan AstBuildLimitException o AstBuildTimeoutException. Si el lector informa que no hay árbol de estructura, el compilador cambia a la ruta sin etiquetar: el compilador heurístico cuando useHeuristic es verdadero, de lo contrario el compilador alternativo simple. Los cuadros delimitadores se adjuntan analizando el flujo de contenido de cada página dentro del rango; una página cuyo flujo de contenido no se puede analizar se omite y deja intacto el resto del árbol.
AstNode es inmutable. Las actualizaciones del árbol reconstruyen los nodos afectados de abajo arriba; los subárboles sin cambios se devuelven por identidad. AstMutator sigue el mismo contrato: cada mutación devuelve un nuevo AstDocument, reconstruye solo la ruta de la raíz al objetivo y registra una MutationEntry en el MutationLog compartido.
AstWriter aplica un MutationLog en modo OVERLAY como una actualización incremental de solo anexado: nuevos flujos de contenido de superposición, objetos de página actualizados, una sección de referencias cruzadas que cubre solo los objetos nuevos y un tráiler cuyo /Prev apunta al startxref anterior. Los bytes originales se dejan intactos, conforme al modelo de actualización incremental de ISO 32000-2:2020, 7.5.6. El texto de reemplazo dibujado para las entradas Updated escapa \, ( y ) en las cadenas literales, conforme a ISO 32000-2:2020, 7.3.4.2.
AstPdfEmitter::emit() es el inverso simétrico de la lectura del árbol de estructura: los árboles producidos por el lector hacen ida y vuelta hacia árboles estructuralmente equivalentes, salvo la renumeración de identificadores de nodo y las clases de canonicalización documentadas. Los MCID presentes en los nodos se vuelven a emitir literalmente, nunca se reasignan.
Casos límite y modos de fallo
Sección titulada «Casos límite y modos de fallo»- La entrada cifrada se rechaza antes de cualquier trabajo sobre el árbol; no hay resultado de árbol parcial para PDF cifrados. Descifrar primero.
- Techos de recursos: máximo de nodos (predeterminado 100.000), máxima profundidad (predeterminado 200), máxima memoria (predeterminado 256 MiB), tiempo de espera de reloj de pared (predeterminado 30 s). Superar un techo provoca
AstBuildLimitException; el tiempo de espera provocaAstBuildTimeoutException, una subclase. - El rango de páginas está basado en 0 y es inclusivo; los límites nulos significan todas las páginas.
- Una página cuyo flujo de contenido no se puede analizar se omite durante el adjunto de cuadros delimitadores; el resto del árbol no se ve afectado.
AstCache::get()nunca lanza: las cargas malformadas, manipuladas o no textuales devuelven null y fuerzan una recompilación.AstCache::set()falla de forma ruidosa cuando falla la escritura del backend o la relectura inmediata.AstMutatorprovocaInvalidArgumentExceptioncuando no se encuentra el identificador del nodo. Las claves de actualización desconocidas se ignoran silenciosamente; solo se aplicatext_content.AstWriter::write()provocaAstWriteExceptioncuando la entrada carece de un encabezado%PDF-o de unstartxreflocalizable. Las entradas sin cuadro delimitador se omiten silenciosamente. Las páginas que no se pueden localizar mediante barrido de objetos —por ejemplo, con flujos de referencias cruzadas comprimidos— se omiten; si no se puede aplicar ninguna superposición, los bytes de entrada se devuelven sin cambios.- La salida OVERLAY no es redacción. El rectángulo blanco y el texto redibujado se anexan; los bytes de contenido original permanecen en el archivo y son recuperables mediante extracción en bruto. No usarlo para el borrado del Art. 17 del RGPD ni para redacción legal. En el árbol de fuentes existe un escritor en modo reconstrucción, pero está marcado como interno, no está listo para producción y queda fuera de la superficie de API compatible.
- La geometría de superposición asume A4 vertical (595 x 842 pt) porque el escritor no lee el MediaBox de la página. En páginas no A4, la superposición puede quedar ligeramente desalineada; la salida sigue siendo estructuralmente válida.
writeAndVerify()comprueba solo la estructura: encabezado,%%EOFfinal y crecimiento de la salida. No vuelve a analizar semánticamente el documento mutado.AstPdfEmitter::emit()provocaAstEmitExceptioncuando la raíz no es un nodo Document o no tiene hijos. Las entradas complementarias OBJR (de anotación) no se emiten en esta versión.- Este módulo no realiza operaciones criptográficas ni define comportamiento específico de FIPS. SHA-256 aparece únicamente como direccionamiento por contenido para las claves de caché.
Conformidad
Sección titulada «Conformidad»La ruta del árbol de estructura lee las facilidades de estructura lógica de PDF etiquetado definidas por ISO 32000-2; el corpus RAG disponible en el momento de la redacción no incluye las cláusulas de estructura lógica, por lo que esa afirmación está fundamentada en el producto a partir de las anotaciones de la fuente. El diseño de actualización incremental del escritor sigue ISO 32000-2:2020, 7.5.6 (citado más abajo), y su escape de cadenas literales sigue ISO 32000-2:2020, 7.3.4.2 (citado más abajo).
Estas afirmaciones describen la capacidad frente a las cláusulas citadas. NextPDF no posee ninguna certificación de conformidad, y la compatibilidad con una cláusula no es una afirmación de certificación.
Notas de desarrollo
Sección titulada «Notas de desarrollo»- Componer un
AstBuilderpor cadaPdfReadercargado. Reutilizar unAstCacheentre compilaciones para amortizar el análisis; el diseño de la clave hace que los cambios de opciones se autoinvaliden. - Compartir un único
MutationLogentre unAstMutatory elAstWriterpara que el escritor aplique exactamente la sesión registrada. Llamar aresetLog()entre sesiones de edición independientes. - Establecer
useHeuristicen verdadero para documentos sin etiquetar cuando la agrupación derivada del diseño sea preferible al árbol alternativo simple. - Las compilaciones son deterministas para bytes y opciones idénticos; contar con esto para pruebas de tipo instantánea.
- Capturar los fallos de compilación mediante la jerarquía
NextPDF\Pro\Ast\Exceptiony los fallos de escritura mediante la jerarquíaNextPDF\Pro\Ast\Writer; las dos no comparten una base por debajo deRuntimeException.
Límite de publicación
Sección titulada «Límite de publicación»Esta página documenta únicamente el comportamiento observable externamente y la superficie de API pública compatible. Las rutas de espacios de nombres internos, las clases auxiliares, las tablas de mecanismos, los nombres de archivo de runbook y los prefijos de ticket quedan fuera de alcance.