stabiliteit: Experimenteel
Retained-page-buffer-uitbreiding
In een oogopslag
Sectie met titel “In een oogopslag”Opt-in-uitbreiding, geen legacy-pariteit. Dit constructorargument bestaat niet in legacy-TCPDF 6.x. Het is een NextPDF-uitbreiding. Het is standaard uit; met die uit gedraagt de adapter zich precies zoals voorheen, en
setPage()naar een eerdere pagina werptUnsupportedFeatureExceptionzoals altijd.
Met legacy-TCPDF kun je setPage() aanroepen om terug te gaan naar een eerdere
pagina en door te blijven tekenen. De streaming-adapter kan dat standaard niet —
zodra een pagina is geflusht, is die weg — dus setPage() of lastPage() naar een
eerdere pagina werpt UnsupportedFeatureException. De retained page buffer is de
opt-in die dit aanvulgedrag herstelt bovenop de NextPDF core retained page buffer.
De buffer inschakelen
Sectie met titel “De buffer inschakelen”Geef retainedPageBuffer: true door aan de adapterconstructor. Met de buffer aan
delegeert een setPage()- of lastPage()-aanroep die op een eerdere pagina mikt
naar de core-aanvulling in plaats van te werpen:
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\TCPDF;
$pdf = new TCPDF(retainedPageBuffer: true);
$pdf->AddPage(); // page 1 — reserve room for a running total$pdf->Cell(0, 10, 'Invoice', ln: 1);
$pdf->AddPage(); // page 2 — line items$pdf->Cell(0, 10, 'Line items…', ln: 1);$total = 1234.56; // known only after the items are laid out
$pdf->setPage(1); // delegates to the core back-fill$pdf->Cell(0, 10, 'Grand total: ' . number_format($total, 2), ln: 1);$pdf->lastPage(); // return to the final page
$pdf->Output(__DIR__ . '/invoice.pdf', 'F');Productievoorbeeld: een gereserveerde voorpagina aanvullen
Sectie met titel “Productievoorbeeld: een gereserveerde voorpagina aanvullen”Een veelvoorkomende reden om naar de buffer te grijpen is een voor- of
samenvattingspagina waarvan de getallen pas bekend zijn nadat de body is opgemaakt
— een totaal paginaaantal, een totaalbedrag, een recordaantal. Reserveer pagina 1
vooraf, render de body, vul dan de voorpagina aan met setPage(1), en hervat aan het
einde met lastPage(). Dit voorbeeld toont ook de twee fail-closed-grenzen die je
moet afhandelen: de UnsupportedFeatureException van de adapter voor een
paginanummer buiten bereik, en de core-RetainedPageBufferIncompatibleException als
het document ook een incompatibele functie inschakelt.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\Exception\UnsupportedFeatureException;use NextPDF\Compat\Tcpdf\TCPDF;use NextPDF\Exception\Strict\RetainedPageBufferIncompatibleException;
/** * Render a multi-page report whose cover page summarises figures that are * only known once every body page has been laid out. * * @param list<array{label: string, amount: float}> $lineItems */function renderReport(array $lineItems, string $destination): void{ // Opt in to the back-fill buffer. Default-off; this is a NextPDF // extension, not legacy TCPDF parity. (Underlying core feature: 6.1.0.) $pdf = new TCPDF(retainedPageBuffer: true);
// Page 1 — the cover. Reserve it now; the summary is filled in last. $pdf->AddPage(); $pdf->Cell(0, 10, 'Quarterly report', ln: 1);
// Body pages — lay out the line items, accumulating the running total. $pdf->AddPage(); $total = 0.0; foreach ($lineItems as $item) { $total += $item['amount']; $pdf->Cell(0, 8, $item['label'] . ': ' . number_format($item['amount'], 2), ln: 1); }
// Back-fill the cover with figures known only now. setPage() delegates to // the core back-fill in retained mode; an out-of-range page number still // fails closed with UnsupportedFeatureException in BOTH modes. try { $pdf->setPage(1); } catch (UnsupportedFeatureException $e) { throw new RuntimeException('Cover page was not reserved: ' . $e->getMessage(), previous: $e); } $pdf->Cell(0, 10, 'Total: ' . number_format($total, 2), ln: 1); $pdf->Cell(0, 10, 'Line items: ' . count($lineItems), ln: 1);
// Resume appending at the final page before output. $pdf->lastPage();
// Output() drives the core build. If the document had also enabled a // back-fill-incompatible feature (signing, tagging, PDF/A, linearization, // object streams, encryption, Safe CSS mode), the core refuses here, // order-independently, with RetainedPageBufferIncompatibleException — the // back-fill can never silently corrupt such a document. try { $pdf->Output($destination, 'F'); } catch (RetainedPageBufferIncompatibleException $e) { // $e->feature names the incompatible feature, e.g. 'signature'. throw new RuntimeException( 'Back-fill is incompatible with ' . $e->feature . '; render pages in order instead.', previous: $e, ); }}Onderscheid de twee mislukkingsoppervlakken bewust:
UnsupportedFeatureException(adapter) — een buiten bereik liggendsetPage()- /lastPage()-doel, of elke schakeling naar een eerdere pagina wanneer de buffer uit is.RetainedPageBufferIncompatibleException(core,NextPDF\Exception\Strict) — de buffer is aan maar gecombineerd met een functie waarvan de paginaniveau -metadata niet opnieuw kan worden afgeleid na een aanvulling. Er is geenRetainedPageBufferInconsistency-type; dit is de enige incompatibiliteitsexception, en een budgetoverschrijding verschijnt als\OverflowException.
Fail-closed-grens
Sectie met titel “Fail-closed-grens”De adapter delegeert naar de core retained page buffer, dus dezelfde weigeringen gelden. Aanvullen wordt geweigerd — ordeonafhankelijk en vóór serialisatie — wanneer het document ook een van de volgende gebruikt:
- Een digitale handtekening.
- Tagged PDF (structuurboom).
- PDF/A.
- Linearization.
- Object-stream-packing.
- Encryptie.
- Safe CSS-renderingmodus.
Elke weigering is een getypeerde, fail-closed exception — nooit een stille drop:
- Het combineren van de buffer met een van de bovenstaande functies werpt de core
RetainedPageBufferIncompatibleException(namespaceNextPDF\Exception\Strict,@sincecore 6.1.0). De controle is ordeonafhankelijk: hij vuurt of de incompatibele functie nu vóór of na de buffer werd opt-in gegeven. - Een budget van 16 MiB ongecomprimeerde bytes per document begrenst de buffer;
het overschrijden ervan werpt
\OverflowExceptionbij het bouwen in plaats van een aangevulde pagina te droppen.
Het punt van de weigering is dat een aanvulling nooit stilletjes een ondertekend of versleuteld document kan wijzigen — de twee kunnen niet samen worden ingeschakeld.
Gedragsnotities
Sectie met titel “Gedragsnotities”- Standaard uit. Construeer zonder de vlag en de adapter is onveranderd;
setPage()naar een eerdere pagina werpt nog steedsUnsupportedFeatureException. Dit behoudt het streamingcontract voor elke bestaande aanroeper. - Geen legacy-pariteit. Legacy-TCPDF heeft geen
retainedPageBuffer-constructorvlag. Documenteer dit als een NextPDF-uitbreiding wanneer je migreert, zodat een toekomstige lezer het niet aanziet voor een TCPDF-functie. lastPage()keert terug naar het einde. Roep na een aanvullinglastPage()aan om het appenden op de laatste pagina te hervatten.- Plan één modus. Als het document moet worden ondertekend, getagd, PDF/A, gelineariseerd, versleuteld of object-streamd, schakel de buffer dan niet in; bereken in plaats daarvan vooraf de waarde die je zou hebben aangevuld.