İçeriğe geç
getnextpdf.com

kararlılık: Deneysel

Korunan sayfa arabelleği uzantısı

Katılımlı uzantı, eski eşlik değil. Bu yapıcı argümanı eski TCPDF 6.x’te bulunmaz. Bir NextPDF uzantısıdır. Varsayılan olarak kapalıdır; kapalıyken adaptör tam olarak öncekiyle aynı davranır ve daha önceki bir sayfaya setPage(), her zaman olduğu gibi UnsupportedFeatureException yükseltir.

Eski TCPDF, daha önceki bir sayfaya geri dönüp çizmeye devam etmek için setPage() çağırmanıza olanak tanır. Akış adaptörü bunu varsayılan olarak yapamaz — bir sayfa boşaltıldıktan sonra gitmiştir — bu nedenle daha önceki bir sayfaya setPage() ya da lastPage(), UnsupportedFeatureException yükseltir. Korunan sayfa arabelleği, bu geri doldurma davranışını NextPDF çekirdek korunan sayfa arabelleğinin üzerine geri getiren katılımlı seçenektir.

Adaptör yapıcısına retainedPageBuffer: true geçirin. Arabellek açıkken, daha önceki bir sayfayı hedefleyen bir setPage() ya da lastPage() çağrısı, yükseltme yerine çekirdek geri doldurmaya yetki devreder:

<?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');

Üretim örneği: ayrılmış bir kapak sayfasını geri doldurma

“Üretim örneği: ayrılmış bir kapak sayfasını geri doldurma” başlıklı bölüm

Arabelleğe başvurmak için yaygın bir neden, sayıları yalnızca gövde yerleştirildikten sonra bilinen bir kapak ya da özet sayfasıdır — bir toplam sayfa sayısı, bir genel toplam, bir kayıt sayısı. Sayfa 1’i en başta ayırın, gövdeyi işleyin, ardından kapağı setPage(1) ile geri doldurun ve sonda lastPage() ile devam edin. Bu örnek ayrıca ele almanız gereken iki hata-durumunda-kapalı sınırı da gösterir: aralık dışı bir sayfa numarası için adaptörün UnsupportedFeatureException istisnası ve belge uyumsuz bir özelliği de etkinleştirirse çekirdek RetainedPageBufferIncompatibleException istisnası.

<?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,
);
}
}

İki hata yüzeyini kasıtlı olarak ayırt edin:

  • UnsupportedFeatureException (adaptör) — aralık dışı bir setPage() / lastPage() hedefi ya da arabellek kapalıyken herhangi bir daha önceki sayfa geçişi.
  • RetainedPageBufferIncompatibleException (çekirdek, NextPDF\Exception\Strict) — arabellek açıktır ama bir geri doldurmadan sonra sayfa düzeyindeki üst verisi yeniden türetilemeyen bir özellikle birleştirilmiştir. Bir RetainedPageBufferInconsistency türü yoktur; bu, tek uyumsuzluk istisnasıdır ve bir bütçe ihlali \OverflowException olarak yüzeye çıkar.

Adaptör çekirdek korunan sayfa arabelleğine yetki devreder; bu nedenle aynı reddetmeler geçerlidir. Geri doldurma — sıradan bağımsız olarak ve serileştirmeden önce — belge şunlardan herhangi birini de kullandığında reddedilir:

  • Bir dijital imza.
  • Etiketli PDF (yapı ağacı).
  • PDF/A.
  • Doğrusallaştırma.
  • Nesne-akışı paketleme.
  • Şifreleme.
  • Safe CSS işleme kipi.

Her reddetme türlenmiş, hata-durumunda-kapalı bir istisnadır — asla sessiz bir düşürme değil:

  • Arabelleği yukarıdaki herhangi bir özellikle birleştirmek, çekirdek RetainedPageBufferIncompatibleException istisnasını yükseltir (ad alanı NextPDF\Exception\Strict, @since çekirdek 6.1.0). Denetim sıradan bağımsızdır: uyumsuz özelliğin arabellek katılımından önce ya da sonra yapılandırılmasından bağımsız olarak tetiklenir.
  • Belge başına 16 MiB sıkıştırılmamış-bayt bütçesi arabelleği sınırlar; bunu aşmak, geri doldurulmuş bir sayfayı düşürmek yerine yapım sırasında \OverflowException yükseltir.

Reddetmenin amacı, bir geri doldurmanın imzalı ya da şifreli bir belgeyi asla sessizce değiştirememesidir — ikisi birlikte etkinleştirilemez.

  • Varsayılan olarak kapalı. Bayrak olmadan oluşturun ve adaptör değişmez; daha önceki bir sayfaya setPage() hâlâ UnsupportedFeatureException yükseltir. Bu, mevcut her çağıran için akış sözleşmesini korur.
  • Eski eşlik değil. Eski TCPDF’te retainedPageBuffer yapıcı bayrağı yoktur. Bunu, taşıma sırasında bir NextPDF uzantısı olarak belgeleyin; böylece gelecekteki bir okuyucu onu bir TCPDF özelliğiyle karıştırmaz.
  • lastPage() sona döner. Bir geri doldurmadan sonra, son sayfada eklemeyi sürdürmek için lastPage() çağırın.
  • Tek bir kip planlayın. Belge imzalanmalı, etiketlenmeli, PDF/A, doğrusallaştırılmalı, şifrelenmeli ya da nesne-akışlı olmalıysa arabelleği etkinleştirmeyin; bunun yerine geri dolduracağınız değeri önceden hesaplayın.