Pular para o conteúdo
getnextpdf.com

estabilidade: Experimental

PageBackfill: buffer de página retida

Pré-visualização opcional. O buffer de página retida é desativado por padrão. Com ele desativado, o escritor é o serializador em streaming que sempre foi — idêntico byte a byte. Ative-o somente quando você realmente precisar desenhar em uma página anterior, e leia primeiro a lista de falha fechada abaixo.

Por padrão, o escritor envia as páginas em streaming e as descarrega em ordem; uma vez que uma página é descarregada, não é mais possível desenhar nela. O buffer de página retida é o recurso opcional que mantém as páginas descarregadas para que uma página já descarregada possa ser preenchida posteriormente — desenhada em uma página anterior — antes de o documento ser serializado. O uso clássico é uma caixa de total ou de resumo que você só pode posicionar depois que as páginas posteriores tiverem sido dispostas.

Terminal window
composer require nextpdf/core:^3

O buffer de página retida é entregue no pacote core. Config::withRetainedPageBuffer() e os métodos de preenchimento posterior de Document são @since 6.1.0. O padrão permanece o escritor em streaming. A ADR-037, que anteriormente havia adiado essa capacidade, agora está registrada como implementada.

Config::withRetainedPageBuffer() opta um documento por páginas retidas. Uma vez ativado, Document::setActiveBackfillPage(int $pageIndex) redireciona o desenho para uma página anterior, já descarregada; Document::endPageBackfill() retorna o desenho à posição normal de anexação. O conteúdo que você escreve entre as duas chamadas chega à página anterior. O buffer mantém as páginas até save(), então o preenchimento posterior é aplicado antes de a tabela de referências cruzadas e o trailer serem gravados (ISO 32000-2 §7.5).

Limite de falha fechada — combinações recusadas

Seção intitulada “Limite de falha fechada — combinações recusadas”

O preenchimento posterior é uma operação de acesso aleatório, e vários recursos de documento pressupõem bytes em streaming, somente de anexação (append-only). O buffer de página retida se recusa a combinar com qualquer um deles, de forma independente da ordem e antes da serialização, para que nunca possa quebrar silenciosamente uma assinatura ou uma reivindicação de conformidade:

  • Uma assinatura digital.
  • PDF marcado (árvore de estrutura).
  • PDF/A.
  • Linearização.
  • Empacotamento de object stream.
  • Criptografia.
  • Modo de renderização Safe CSS.

Um orçamento de bytes não comprimidos por documento limita quanto o buffer pode manter; um documento que o excede falha de forma rígida em vez de consumir memória sem limite. O padrão de streaming ainda falha fechado no momento em que um chamador tenta uma troca de acesso aleatório sem o recurso opcional — ativar o buffer é a única forma de obter o preenchimento posterior, e ele é incompatível com os recursos acima por construção.

SímboloLocalizaçãoFunção
Config::withRetainedPageBuffer(bool $enabled = true): selfsrc/Core/Config.phpOpta um documento pelo buffer de página retida.
Document::setActiveBackfillPage(int $pageIndex): staticsrc/Core/Document.phpRedireciona o desenho para uma página anterior, já descarregada.
Document::endPageBackfill(): staticsrc/Core/Document.phpRetorna o desenho à posição normal de anexação.

Uma tentativa de preenchimento posterior que viola uma combinação recusada levanta uma exceção de configuração tipada no limite, não um documento corrompido.

Reserve um espaço na página um, preencha o resto do documento e então preencha posteriormente o espaço reservado com um valor calculado no 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');

Mantenha o buffer desativado para qualquer documento assinado, marcado, PDF/A, linearizado, criptografado ou com object stream — essas são exatamente as combinações que o buffer recusa. Escolha um caminho explicitamente.

<?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);
}
  • Desativado é idêntico byte a byte. Com o buffer desativado, o escritor faz streaming como antes.
  • Mutuamente exclusivo com assinatura, marcação (tagging), PDF/A, linearização, object streams, criptografia e o modo Safe CSS. A recusa é independente da ordem e dispara antes da serialização. Planeje o documento para um modo ou o outro.
  • Um orçamento de bytes falha de forma rígida. O buffer retido é limitado; um documento que excede o orçamento de bytes não comprimidos falha em vez de crescer sem limite.
  • Emparelhe as chamadas. Cada setActiveBackfillPage() deve ser correspondido por um endPageBackfill() para que o conteúdo posterior seja anexado normalmente.
  • O padrão de streaming recusa acesso aleatório. Sem o recurso opcional, uma troca de acesso aleatório falha fechada. O buffer é o único caminho suportado.

O buffer de página retida troca memória pela capacidade de preenchimento posterior: ele mantém as páginas descarregadas até save(), limitado pelo orçamento de bytes não comprimidos por documento. O perfil de memória plano do escritor em streaming se aplica apenas com o buffer desativado. O performance_budget (wall_ms: 1500, peak_mb: 128) reflete o teto de memória mais alto do caminho retido.

O buffer de página retida não amplia a superfície de entrada; ele altera quando os bytes são serializados, não o que é ingerido. Sua recusa em combinar com criptografia e assinatura é uma propriedade de segurança: um preenchimento posterior nunca pode alterar bytes assinados ou criptografados após o fato, porque os dois não podem ser ativados juntos. O orçamento de bytes limita a memória contra um documento hostil.

DeclaraçãoEspecificaçãoCláusula
O escritor serializa o corpo, a estrutura de referências cruzadas e o trailer no momento do salvamento.ISO 32000-2§7.5

Esta é uma capacidade de pré-visualização. O NextPDF recusa o buffer de preenchimento posterior para documentos assinados, marcados, PDF/A, linearizados, criptografados e com object stream, de modo que não faz nenhuma reivindicação de conformidade para esses perfis por este caminho. Nenhum texto de norma é reproduzido.

O adaptador de compatibilidade TCPDF expõe essa capacidade como uma extensão de construtor. Construa o adaptador com retainedPageBuffer: true, e então uma chamada setPage() ou lastPage() que aponte para uma página anterior delega ao preenchimento posterior do core em vez de levantar a UnsupportedFeatureException de streaming. Este argumento de construtor é uma extensão do NextPDF, não paridade com o TCPDF legado — o TCPDF legado não tem tal flag. As mesmas recusas de falha fechada se aplicam. Consulte a página do buffer de página retida do adaptador de compatibilidade para os detalhes do lado do adaptador.