stabilitas: Eksperimental
Ekstensi buffer halaman dipertahankan
Sekilas
Bagian berjudul “Sekilas”Ekstensi opt-in, bukan paritas legacy. Argumen konstruktor ini tidak ada dalam TCPDF 6.x legacy. Ini adalah ekstensi NextPDF. Ia default-mati; dengan ia mati, adapter berperilaku persis seperti sebelumnya, dan
setPage()ke halaman terdahulu memunculkanUnsupportedFeatureExceptionsebagaimana selalu.
TCPDF legacy memungkinkan Anda memanggil setPage() untuk kembali ke halaman
terdahulu dan terus menggambar. Adapter streaming tidak dapat melakukan itu secara
default — begitu sebuah halaman di-flush, ia hilang — sehingga setPage() atau
lastPage() ke halaman terdahulu memunculkan UnsupportedFeatureException.
Buffer halaman dipertahankan adalah opt-in yang memulihkan perilaku
pengisian-ulang ini di atas buffer halaman dipertahankan core NextPDF.
Mengaktifkan buffer
Bagian berjudul “Mengaktifkan buffer”Berikan retainedPageBuffer: true ke konstruktor adapter. Dengan buffer aktif,
sebuah panggilan setPage() atau lastPage() yang menargetkan halaman terdahulu
mendelegasikan ke pengisian-ulang core alih-alih memunculkan eksepsi:
<?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');Contoh produksi: mengisi-ulang halaman sampul yang dicadangkan
Bagian berjudul “Contoh produksi: mengisi-ulang halaman sampul yang dicadangkan”Alasan umum untuk meraih buffer adalah halaman sampul atau ringkasan yang
angkanya baru diketahui setelah body ditata — total jumlah halaman, grand
total, hitungan rekaman. Cadangkan halaman 1 di muka, render body, lalu isi-ulang
sampul dengan setPage(1), dan lanjutkan di akhir dengan lastPage(). Contoh ini
juga menunjukkan dua batasan fail-closed yang harus Anda tangani:
UnsupportedFeatureException adapter untuk nomor halaman di-luar-rentang, dan
RetainedPageBufferIncompatibleException core jika dokumen juga mengaktifkan
fitur yang tidak kompatibel.
<?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, ); }}Bedakan kedua permukaan kegagalan secara sengaja:
UnsupportedFeatureException(adapter) — targetsetPage()/lastPage()yang di-luar-rentang, atau peralihan halaman-terdahulu apa pun saat buffer mati.RetainedPageBufferIncompatibleException(core,NextPDF\Exception\Strict) — buffer aktif tetapi digabung dengan fitur yang metadata tingkat-halamannya tidak dapat diturunkan ulang setelah pengisian-ulang. Tidak ada tipeRetainedPageBufferInconsistency; ini adalah satu-satunya eksepsi ketidakkompatibelan, dan pelanggaran anggaran muncul sebagai\OverflowException.
Batasan fail-closed
Bagian berjudul “Batasan fail-closed”Adapter mendelegasikan ke buffer halaman dipertahankan core, sehingga penolakan yang sama berlaku. Pengisian-ulang ditolak — terlepas dari urutan dan sebelum serialisasi — saat dokumen juga memakai salah satu dari:
- Sebuah tanda tangan digital.
- PDF bertag (pohon struktur).
- PDF/A.
- Linearisasi.
- Pengemasan object stream.
- Enkripsi.
- Mode rendering Safe CSS.
Setiap penolakan adalah eksepsi bertipe dan fail-closed — tidak pernah drop diam:
- Menggabungkan buffer dengan fitur mana pun di atas memunculkan
RetainedPageBufferIncompatibleExceptioncore (namespaceNextPDF\Exception\Strict,@sincecore 6.1.0). Pemeriksaannya terlepas dari urutan: ia terpicu baik fitur tak-kompatibel dikonfigurasikan sebelum atau setelah buffer di-opt-in. - Anggaran byte-tak-terkompresi per-dokumen 16 MiB membatasi buffer;
melampauinya memunculkan
\OverflowExceptionpada waktu build alih-alih mendrop halaman yang sudah diisi-ulang.
Inti dari penolakan ini adalah bahwa pengisian-ulang tidak akan pernah dapat diam-diam mengubah dokumen yang ditandatangani atau terenkripsi — keduanya tidak dapat diaktifkan bersama.
Catatan perilaku
Bagian berjudul “Catatan perilaku”- Default-mati. Konstruksi tanpa flag dan adapter tidak berubah;
setPage()ke halaman terdahulu tetap memunculkanUnsupportedFeatureException. Ini mempertahankan kontrak streaming bagi setiap pemanggil yang sudah ada. - Bukan paritas legacy. TCPDF legacy tidak memiliki flag konstruktor
retainedPageBuffer. Dokumentasikan ini sebagai ekstensi NextPDF saat Anda bermigrasi, agar pembaca di masa depan tidak salah mengiranya sebagai fitur TCPDF. lastPage()kembali ke akhir. Setelah pengisian-ulang, panggillastPage()untuk melanjutkan append pada halaman terakhir.- Rencanakan satu mode. Jika dokumen harus ditandatangani, bertag, PDF/A, ter-linearisasi, terenkripsi, atau object-streamed, jangan aktifkan buffer; pra-hitung nilai yang akan Anda isi-ulang sebagai gantinya.