estabilidad: Experimental
PageBackfill: búfer de páginas retenidas
De un vistazo
Sección titulada «De un vistazo»Vista previa opcional. El búfer de páginas retenidas está desactivado por defecto. Con él desactivado, el escritor es el serializador por streaming que siempre ha sido —idéntico byte a byte—. Actívelo solo cuando realmente necesite dibujar sobre una página anterior, y lea primero la lista de cierre seguro de abajo.
Por defecto, el escritor transmite las páginas y las vuelca en orden; una vez que una página se vuelca, ya no se puede dibujar sobre ella. El búfer de páginas retenidas es la opción que retiene las páginas volcadas para que una página ya volcada pueda rellenarse a posteriori —dibujarse sobre una página anterior— antes de que el documento se serialice. El uso clásico es un total o una caja de resumen que solo puede colocarse después de que se hayan maquetado las páginas posteriores.
Instalación
Sección titulada «Instalación»composer require nextpdf/core:^3El búfer de páginas retenidas se incluye en el paquete core.
Config::withRetainedPageBuffer() y los métodos de relleno a posteriori de
Document son @since 6.1.0. El valor predeterminado sigue siendo el escritor
por streaming. ADR-037, que previamente había diferido esta capacidad, ahora se
registra como implementado.
Panorama conceptual
Sección titulada «Panorama conceptual»Config::withRetainedPageBuffer() opta un documento por las páginas retenidas.
Una vez activado, Document::setActiveBackfillPage(int $pageIndex) redirige el
dibujo a una página anterior ya volcada; Document::endPageBackfill() devuelve el
dibujo a la posición normal de anexado. El contenido que escriba entre las dos
llamadas aterriza en la página anterior. El búfer retiene las páginas hasta
save(), de modo que el relleno a posteriori se aplica antes de que se escriban
la tabla de referencias cruzadas y el tráiler (ISO 32000-2 §7.5).
Límite de cierre seguro — combinaciones rechazadas
Sección titulada «Límite de cierre seguro — combinaciones rechazadas»El relleno a posteriori es una operación de acceso aleatorio, y varias características del documento asumen bytes anexados solo en streaming. El búfer de páginas retenidas se niega a combinarse con cualquiera de ellas, de forma independiente del orden y antes de la serialización, de modo que nunca puede romper silenciosamente una firma o una reclamación de conformidad:
- Una firma digital.
- PDF etiquetado (árbol de estructura).
- PDF/A.
- Linealización.
- Empaquetado en flujos de objetos.
- Cifrado.
- Modo de representación Safe de CSS.
Un presupuesto de bytes sin comprimir por documento limita cuánto puede retener el búfer; un documento que lo excede falla de forma dura en lugar de consumir memoria sin límite. El valor predeterminado de streaming aún se cierra de forma segura en el momento en que un llamador intenta un cambio de acceso aleatorio sin la opción: activar el búfer es la única manera de obtener el relleno a posteriori, y es incompatible con las características de arriba por construcción.
Superficie de la API
Sección titulada «Superficie de la API»| Símbolo | Ubicación | Función |
|---|---|---|
Config::withRetainedPageBuffer(bool $enabled = true): self | src/Core/Config.php | Opta un documento por el búfer de páginas retenidas. |
Document::setActiveBackfillPage(int $pageIndex): static | src/Core/Document.php | Redirige el dibujo a una página anterior ya volcada. |
Document::endPageBackfill(): static | src/Core/Document.php | Devuelve el dibujo a la posición normal de anexado. |
Un intento de relleno a posteriori que viola una combinación rechazada lanza una excepción de configuración tipada en el límite, no un documento corrupto.
Ejemplo de código — Inicio rápido
Sección titulada «Ejemplo de código — Inicio rápido»Reserve un espacio en la página uno, complete el resto del documento y luego rellene el espacio reservado con un valor calculado al final.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;use NextPDF\Core\Document;
$config = (new Config())->withRetainedPageBuffer();
$doc = Document::createStandalone($config);$doc->addPage(); // page 0 — leaves room for a grand total$doc->writeHtml('<h1>Invoice</h1>');
$doc->addPage(); // page 1 — line items$doc->writeHtml('<p>Line items…</p>');$total = 1234.56; // computed after laying out the items
$doc->setActiveBackfillPage(0); // draw back onto page 0$doc->writeHtml('<p>Grand total: ' . number_format($total, 2) . '</p>');$doc->endPageBackfill();
$doc->save(__DIR__ . '/invoice.pdf');Ejemplo de código — Producción
Sección titulada «Ejemplo de código — Producción»Mantenga el búfer desactivado para cualquier documento firmado, etiquetado, PDF/A, linealizado, cifrado o con flujos de objetos: esas son exactamente las combinaciones que el búfer rechaza. Elija una ruta de forma explícita.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;use NextPDF\Core\Document;
function renderReport(bool $needsBackfill, bool $mustBeSigned): Document{ if ($needsBackfill && $mustBeSigned) { // The buffer refuses to combine with signing. Resolve the requirement // before building: pre-compute the value, or sign a separate pass. throw new \LogicException('Back-fill and signing are mutually exclusive.'); }
$config = new Config(); if ($needsBackfill) { $config = $config->withRetainedPageBuffer(); }
return Document::createStandalone($config);}Casos límite y trampas
Sección titulada «Casos límite y trampas»- Desactivado es idéntico byte a byte. Con el búfer desactivado, el escritor transmite como antes.
- Mutuamente excluyente con firma, etiquetado, PDF/A, linealización, flujos de objetos, cifrado y el modo Safe de CSS. El rechazo es independiente del orden y se dispara antes de la serialización. Planee el documento para un modo o el otro.
- Un presupuesto de bytes falla de forma dura. El búfer retenido está acotado; un documento que excede el presupuesto de bytes sin comprimir falla en lugar de crecer sin límite.
- Empareje las llamadas. Cada
setActiveBackfillPage()debe ir emparejada con unendPageBackfill()para que el contenido posterior se anexe con normalidad. - El valor predeterminado de streaming rechaza el acceso aleatorio. Sin la opción, un cambio de acceso aleatorio se cierra de forma segura. El búfer es la única ruta admitida.
Rendimiento
Sección titulada «Rendimiento»El búfer de páginas retenidas intercambia memoria por la capacidad de relleno a
posteriori: retiene las páginas volcadas hasta save(), acotado por el
presupuesto de bytes sin comprimir por documento. El perfil de memoria plano del
escritor por streaming se aplica solo con el búfer desactivado. El
performance_budget (wall_ms: 1500, peak_mb: 128) refleja el techo de
memoria más alto de la ruta retenida.
Notas de seguridad
Sección titulada «Notas de seguridad»El búfer de páginas retenidas no amplía la superficie de entrada; cambia cuándo se serializan los bytes, no qué se ingiere. Su negativa a combinarse con el cifrado y la firma es una propiedad de seguridad: un relleno a posteriori nunca puede alterar bytes firmados o cifrados a posteriori, porque ambos no pueden habilitarse a la vez. El presupuesto de bytes acota la memoria frente a un documento hostil.
Conformidad
Sección titulada «Conformidad»| Afirmación | Especificación | Cláusula |
|---|---|---|
| El escritor serializa el cuerpo, la estructura de referencias cruzadas y el tráiler en el momento de guardar. | ISO 32000-2 | §7.5 |
Esta es una capacidad de vista previa. NextPDF rechaza el búfer de relleno a posteriori para documentos firmados, etiquetados, PDF/A, linealizados, cifrados y con flujos de objetos, de modo que no hace ninguna reclamación de conformidad para esos perfiles a través de esta ruta. No se reproduce ningún texto de las normas.
Adaptador de compatibilidad (TCPDF)
Sección titulada «Adaptador de compatibilidad (TCPDF)»El adaptador de compatibilidad con TCPDF expone esta capacidad como una extensión
del constructor. Construya el adaptador con retainedPageBuffer: true, y
entonces una llamada setPage() o lastPage() que apunte a una página anterior
delega en el relleno a posteriori del core en lugar de lanzar la
UnsupportedFeatureException del streaming. Este argumento del constructor es una
extensión de NextPDF, no paridad con el TCPDF heredado: el TCPDF heredado no
tiene ese indicador. Se aplican los mismos rechazos de cierre seguro. Consulte la
página de búfer de páginas retenidas del adaptador de compatibilidad para conocer
los detalles del lado del adaptador.