stabiliteit: Experimenteel
PageBackfill: retained page buffer
In een oogopslag
Sectie met titel “In een oogopslag”Opt-in preview. De retained page buffer staat standaard uit. Met die uit is de writer de streaming-serializer die hij altijd is geweest — byte-identiek. Zet hem alleen aan wanneer je echt op een eerdere pagina moet tekenen, en lees eerst de fail-closed-lijst hieronder.
Standaard streamt de writer pagina’s en flusht ze in volgorde; zodra een pagina is geflusht, kan er niet meer op worden getekend. De retained page buffer is de opt-in die geflushte pagina’s vasthoudt zodat een eerder geflushte pagina kan worden aangevuld — op een eerdere pagina kan worden getekend — voordat het document wordt geserialiseerd. Het klassieke gebruik is een totaal of een samenvattingsvak dat je pas kunt plaatsen nadat latere pagina’s zijn opgemaakt.
Installeren
Sectie met titel “Installeren”composer require nextpdf/core:^3De retained page buffer wordt meegeleverd in het core-pakket.
Config::withRetainedPageBuffer() en de aanvulmethoden van Document zijn
@since 6.1.0. De standaard blijft de streaming-writer. ADR-037, dat dit vermogen
eerder had uitgesteld, is nu vastgelegd als geïmplementeerd.
Conceptueel overzicht
Sectie met titel “Conceptueel overzicht”Config::withRetainedPageBuffer() schakelt een document in voor retained pages.
Eenmaal aan herleidt Document::setActiveBackfillPage(int $pageIndex) het tekenen
naar een eerdere, reeds geflushte pagina; Document::endPageBackfill() brengt het
tekenen terug naar de normale append-positie. Content die je tussen de twee
aanroepen schrijft, komt op de eerdere pagina terecht. De buffer houdt pagina’s vast
tot save(), zodat de aanvulling wordt toegepast voordat de cross-reference table en
trailer worden geschreven (ISO 32000-2 §7.5).
Fail-closed-grens — geweigerde combinaties
Sectie met titel “Fail-closed-grens — geweigerde combinaties”Aanvullen is een random-accessbewerking, en verschillende documentfuncties gaan uit van append-only, gestreamde bytes. De retained page buffer weigert met elk daarvan te combineren, ordeonafhankelijk en vóór serialisatie, zodat hij nooit stilletjes een handtekening of een conformiteitsclaim kan breken:
- Een digitale handtekening.
- Tagged PDF (structuurboom).
- PDF/A.
- Linearization.
- Object-stream-packing.
- Encryptie.
- Safe CSS-renderingmodus.
Een budget voor ongecomprimeerde bytes per document begrenst hoeveel de buffer mag vasthouden; een document dat het overschrijdt, faalt hard in plaats van onbegrensd geheugen te verbruiken. De streamingstandaard faalt nog steeds gesloten op het moment dat een aanroeper een random-accessschakeling probeert zonder de opt-in — de buffer aanzetten is de enige manier om aanvullen te krijgen, en hij is per constructie incompatibel met de bovenstaande functies.
API-oppervlak
Sectie met titel “API-oppervlak”| Symbool | Locatie | Rol |
|---|---|---|
Config::withRetainedPageBuffer(bool $enabled = true): self | src/Core/Config.php | Schakelt een document in voor de retained page buffer. |
Document::setActiveBackfillPage(int $pageIndex): static | src/Core/Document.php | Herleidt het tekenen naar een eerdere, reeds geflushte pagina. |
Document::endPageBackfill(): static | src/Core/Document.php | Brengt het tekenen terug naar de normale append-positie. |
Een aanvulpoging die een geweigerde combinatie schendt, werpt een getypeerde configuratie-exception bij de grens, niet een corrupt document.
Codevoorbeeld — Snelle start
Sectie met titel “Codevoorbeeld — Snelle start”Reserveer een plek op pagina één, vul de rest van het document, en vul dan de gereserveerde plek aan met een waarde die aan het einde wordt berekend.
<?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');Codevoorbeeld — Productie
Sectie met titel “Codevoorbeeld — Productie”Houd de buffer uit voor elk ondertekend, getagd, PDF/A-, gelineariseerd, versleuteld of object-streamdocument — dat zijn precies de combinaties die de buffer weigert. Kies expliciet één pad.
<?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);}Randgevallen en valkuilen
Sectie met titel “Randgevallen en valkuilen”- Uit is byte-identiek. Met de buffer uit streamt de writer zoals voorheen.
- Wederzijds uitsluitend met signing, tagging, PDF/A, linearization, object streams, encryptie en Safe CSS-modus. De weigering is ordeonafhankelijk en vuurt vóór serialisatie. Plan het document voor de ene of de andere modus.
- Een bytesbudget faalt hard. De retained buffer is begrensd; een document dat het budget voor ongecomprimeerde bytes overschrijdt, faalt in plaats van zonder limiet te groeien.
- Koppel de aanroepen. Elke
setActiveBackfillPage()zou moeten worden gematcht door eenendPageBackfill()zodat latere content normaal appendt. - De streamingstandaard weigert random access. Zonder de opt-in faalt een random-accessschakeling gesloten. De buffer is het enige ondersteunde pad.
Prestaties
Sectie met titel “Prestaties”De retained page buffer ruilt geheugen voor het aanvulvermogen: hij houdt geflushte
pagina’s vast tot save(), begrensd door het budget voor ongecomprimeerde bytes per
document. Het vlakke geheugenprofiel van de streaming-writer geldt alleen met de
buffer uit. Het performance_budget (wall_ms: 1500, peak_mb: 128) weerspiegelt
het hogere geheugenplafond van het behouden pad.
Beveiligingsnotities
Sectie met titel “Beveiligingsnotities”De retained page buffer verbreedt het invoeroppervlak niet; hij verandert wanneer bytes worden geserialiseerd, niet wat wordt ingenomen. Zijn weigering om te combineren met encryptie en signing is een veiligheidseigenschap: een aanvulling kan ondertekende of versleutelde bytes nooit achteraf wijzigen, omdat de twee niet samen kunnen worden ingeschakeld. Het bytesbudget begrenst het geheugen tegen een vijandig document.
Conformiteit
Sectie met titel “Conformiteit”| Statement | Spec | Clause |
|---|---|---|
| De writer serialiseert de body, cross-reference-structuur en trailer bij het opslaan. | ISO 32000-2 | §7.5 |
Dit is een previewvermogen. NextPDF weigert de aanvulbuffer voor ondertekende, getagde, PDF/A-, gelineariseerde, versleutelde en object-streamdocumenten, dus het maakt geen conformiteitsclaim voor die profielen via dit pad. Er wordt geen standaardtekst gereproduceerd.
Compat (TCPDF)-adapter
Sectie met titel “Compat (TCPDF)-adapter”De TCPDF-compatibiliteitsadapter stelt dit vermogen beschikbaar als een
constructoruitbreiding. Construeer de adapter met retainedPageBuffer: true, dan
delegeert een setPage()- of lastPage()-aanroep die op een eerdere pagina mikt
naar de core-aanvulling in plaats van de streaming-UnsupportedFeatureException te
werpen. Dit constructorargument is een NextPDF-uitbreiding, geen legacy-TCPDF
pariteit — legacy-TCPDF heeft zo’n vlag niet. Dezelfde fail-closed-weigeringen
gelden. Zie de retained-page-buffer-pagina van de compat-adapter voor de
adapterzijdige details.