độ ổn định: Thử nghiệm
Phần mở rộng bộ đệm trang retained
Tổng quan nhanh
Phần tiêu đề “Tổng quan nhanh”Phần mở rộng opt-in, không phải tương đương cũ. Đối số hàm dựng này không tồn tại trong TCPDF 6.x cũ. Nó là một phần mở rộng NextPDF. Nó mặc định tắt; khi nó tắt, bộ chuyển đổi hành xử hệt như trước, và
setPage()về một trang trước đó làm phát sinhUnsupportedFeatureExceptionnhư xưa nay.
TCPDF cũ cho phép bạn gọi setPage() để quay về một trang trước đó và tiếp tục
vẽ. Bộ chuyển đổi streaming không thể làm điều đó theo mặc định — một khi một
trang đã được flush, nó biến mất — nên setPage() hoặc lastPage() về một trang
trước đó làm phát sinh UnsupportedFeatureException. Bộ đệm trang retained là tùy
chọn opt-in khôi phục hành vi điền bù này trên nền bộ đệm trang retained của
NextPDF core.
Bật bộ đệm
Phần tiêu đề “Bật bộ đệm”Truyền retainedPageBuffer: true vào hàm dựng bộ chuyển đổi. Khi bộ đệm bật, một
lệnh gọi setPage() hoặc lastPage() nhắm vào một trang trước đó sẽ ủy quyền cho
điền bù của core thay vì làm phát sinh:
<?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');Ví dụ sản phẩm: điền bù một trang bìa đã dành
Phần tiêu đề “Ví dụ sản phẩm: điền bù một trang bìa đã dành”Một lý do phổ biến để dùng đến bộ đệm là một trang bìa hay trang tóm tắt mà các
con số chỉ biết được sau khi phần thân đã được dàn xong — tổng số trang, một ô
tổng, một số đếm bản ghi. Hãy dành sẵn trang 1 từ đầu, kết xuất phần thân, rồi điền
bù trang bìa với setPage(1), và tiếp tục ở cuối với lastPage(). Ví dụ này cũng
cho thấy hai ranh giới fail-closed mà bạn phải xử lý: UnsupportedFeatureException
của bộ chuyển đổi cho một số trang ngoài phạm vi, và
RetainedPageBufferIncompatibleException của core nếu tài liệu cũng bật một tính
năng không tương thích.
<?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, ); }}Hãy phân biệt hai bề mặt hỏng một cách có chủ ý:
UnsupportedFeatureException(bộ chuyển đổi) — một mục tiêusetPage()/lastPage()ngoài phạm vi, hoặc bất kỳ lần chuyển sang trang trước đó nào khi bộ đệm tắt.RetainedPageBufferIncompatibleException(core,NextPDF\Exception\Strict) — bộ đệm bật nhưng kết hợp với một tính năng mà siêu dữ liệu cấp trang của nó không thể được suy dẫn lại sau một lần điền bù. Không có kiểuRetainedPageBufferInconsistencynào; đây là ngoại lệ không-tương-thích duy nhất, và một lần vượt ngân sách hiện lên dưới dạng\OverflowException.
Ranh giới fail-closed
Phần tiêu đề “Ranh giới fail-closed”Bộ chuyển đổi ủy quyền cho bộ đệm trang retained của core, nên cùng các từ chối áp dụng. Điền bù bị từ chối — không phụ thuộc thứ tự và trước khi serialize — khi tài liệu cũng dùng bất kỳ tính năng nào trong số:
- Một chữ ký số.
- PDF gắn thẻ (cây cấu trúc).
- PDF/A.
- Linearization.
- Đóng gói object-stream.
- Mã hóa.
- Chế độ kết xuất CSS Safe.
Mỗi lần từ chối là một ngoại lệ có kiểu, fail-closed — không bao giờ là một lần bỏ âm thầm:
- Kết hợp bộ đệm với bất kỳ tính năng nào ở trên làm phát sinh
RetainedPageBufferIncompatibleExceptioncủa core (namespaceNextPDF\Exception\Strict,@sincecore 6.1.0). Phép kiểm tra không phụ thuộc thứ tự: nó kích hoạt dù tính năng không tương thích được cấu hình trước hay sau khi bộ đệm được opt-in. - Một ngân sách byte-chưa-nén 16 MiB theo từng tài liệu chặn bộ đệm; vượt quá
nó làm phát sinh
\OverflowExceptiontại lúc build thay vì bỏ một trang đã điền bù.
Điểm cốt lõi của sự từ chối là một lần điền bù không bao giờ có thể âm thầm làm thay đổi một tài liệu đã ký hay đã mã hóa — cả hai không thể được bật cùng nhau.
Ghi chú hành vi
Phần tiêu đề “Ghi chú hành vi”- Mặc định tắt. Dựng mà không có cờ thì bộ chuyển đổi không đổi;
setPage()về một trang trước đó vẫn làm phát sinhUnsupportedFeatureException. Điều này giữ hợp đồng streaming cho mọi bên gọi hiện có. - Không phải tương đương cũ. TCPDF cũ không có cờ hàm dựng
retainedPageBuffer. Hãy ghi tài liệu điều này như một phần mở rộng NextPDF khi bạn di trú, để một người đọc về sau không nhầm nó là một tính năng TCPDF. lastPage()quay về cuối. Sau một lần điền bù, hãy gọilastPage()để tiếp tục thêm ở trang cuối.- Lập kế hoạch một chế độ. Nếu tài liệu phải được ký, gắn thẻ, PDF/A, linearize, mã hóa, hoặc object-stream, đừng bật bộ đệm; thay vào đó hãy tính trước giá trị mà lẽ ra bạn sẽ điền bù.