stabilność: Eksperymentalna
PageBackfill: zachowany bufor stron
W skrócie
Dział zatytułowany „W skrócie”Opcjonalny podgląd. Zachowany bufor stron jest domyślnie wyłączony. Przy wyłączonym buforze writer jest tym samym serializatorem strumieniowym, którym był zawsze — bajtowo identycznym. Włączaj go tylko wtedy, gdy naprawdę musisz rysować na wcześniejszej stronie, i najpierw przeczytaj poniższą listę fail-closed.
Domyślnie writer strumieniuje strony i wypycha je w kolejności; po wypchnięciu strony nie można już na niej rysować. Zachowany bufor stron to opcja, która przechowuje wypchnięte strony, dzięki czemu wcześniej wypchniętą stronę można uzupełnić — narysować na wcześniejszej stronie — zanim dokument zostanie zserializowany. Klasyczne zastosowanie to suma lub pole podsumowania, które można umieścić dopiero po rozłożeniu późniejszych stron.
Instalacja
Dział zatytułowany „Instalacja”composer require nextpdf/core:^3Zachowany bufor stron jest dostarczany w pakiecie core.
Config::withRetainedPageBuffer() oraz metody uzupełniania w Document to
@since 6.1.0. Wartością domyślną pozostaje writer strumieniowy. ADR-037, który
wcześniej odraczał tę zdolność, jest teraz zapisany jako zaimplementowany.
Przegląd koncepcyjny
Dział zatytułowany „Przegląd koncepcyjny”Config::withRetainedPageBuffer() włącza dla dokumentu strony zachowane. Po
włączeniu Document::setActiveBackfillPage(int $pageIndex) przekierowuje
rysowanie na wcześniejszą, już wypchniętą stronę; Document::endPageBackfill()
zwraca rysowanie do normalnej pozycji dołączania. Treść zapisana między tymi
dwoma wywołaniami trafia na wcześniejszą stronę. Bufor przechowuje strony aż do
save(), więc uzupełnienie jest stosowane przed zapisaniem tablicy odniesień
krzyżowych i trailera (ISO 32000-2 §7.5).
Granica fail-closed — odmawiane kombinacje
Dział zatytułowany „Granica fail-closed — odmawiane kombinacje”Uzupełnianie to operacja swobodnego dostępu, a kilka funkcji dokumentu zakłada bajty tylko dołączane, strumieniowane. Zachowany bufor stron odmawia połączenia z którąkolwiek z nich, niezależnie od kolejności i przed serializacją, tak aby nigdy nie mógł po cichu zepsuć podpisu ani twierdzenia o zgodności:
- Podpis cyfrowy.
- Tagowany PDF (drzewo struktury).
- PDF/A.
- Linearyzacja.
- Pakowanie w strumienie obiektów.
- Szyfrowanie.
- Tryb renderowania Safe CSS.
Budżet nieskompresowanych bajtów na dokument ogranicza, ile bufor może przechować; dokument, który go przekracza, kończy się twardą awarią, zamiast zużywać nieograniczoną pamięć. Domyślne strumieniowanie nadal kończy się niepowodzeniem fail-closed w momencie, gdy wywołujący próbuje przełączenia swobodnego dostępu bez opcji — włączenie bufora jest jedynym sposobem uzyskania uzupełniania, a jest ono z konstrukcji niezgodne z powyższymi funkcjami.
Powierzchnia API
Dział zatytułowany „Powierzchnia API”| Symbol | Lokalizacja | Rola |
|---|---|---|
Config::withRetainedPageBuffer(bool $enabled = true): self | src/Core/Config.php | Włącza dla dokumentu zachowany bufor stron. |
Document::setActiveBackfillPage(int $pageIndex): static | src/Core/Document.php | Przekierowuje rysowanie na wcześniejszą, już wypchniętą stronę. |
Document::endPageBackfill(): static | src/Core/Document.php | Zwraca rysowanie do normalnej pozycji dołączania. |
Próba uzupełnienia, która narusza odmawianą kombinację, zgłasza typowany wyjątek konfiguracji na granicy, a nie uszkodzony dokument.
Przykład kodu — szybki start
Dział zatytułowany „Przykład kodu — szybki start”Zarezerwuj miejsce na stronie pierwszej, wypełnij resztę dokumentu, a następnie uzupełnij zarezerwowane miejsce wartością obliczoną na końcu.
<?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');Przykład kodu — produkcja
Dział zatytułowany „Przykład kodu — produkcja”Trzymaj bufor wyłączony dla każdego dokumentu podpisanego, tagowanego, PDF/A, zlinearyzowanego, zaszyfrowanego lub ze strumieniami obiektów — to dokładnie te kombinacje, których bufor odmawia. Wybierz jedną ścieżkę jawnie.
<?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);}Przypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”- Wyłączony jest bajtowo identyczny. Przy wyłączonym buforze writer strumieniuje jak wcześniej.
- Wyklucza się wzajemnie z podpisywaniem, tagowaniem, PDF/A, linearyzacją, strumieniami obiektów, szyfrowaniem i trybem Safe CSS. Odmowa jest niezależna od kolejności i następuje przed serializacją. Zaplanuj dokument dla jednego trybu albo drugiego.
- Budżet bajtów kończy się twardą awarią. Zachowany bufor jest ograniczony; dokument, który przekracza budżet nieskompresowanych bajtów, kończy się awarią, a nie rośnie bez limitu.
- Paruj wywołania. Każde
setActiveBackfillPage()powinno być sparowane zendPageBackfill(), aby późniejsza treść dołączała się normalnie. - Domyślne strumieniowanie odmawia swobodnego dostępu. Bez opcji przełączenie swobodnego dostępu kończy się niepowodzeniem fail-closed. Bufor to jedyna obsługiwana ścieżka.
Wydajność
Dział zatytułowany „Wydajność”Zachowany bufor stron wymienia pamięć na zdolność uzupełniania: przechowuje
wypchnięte strony aż do save(), ograniczony budżetem nieskompresowanych bajtów
na dokument. Płaski profil pamięciowy writera strumieniowego obowiązuje wyłącznie
przy wyłączonym buforze. performance_budget (wall_ms: 1500, peak_mb: 128)
odzwierciedla wyższy pułap pamięci ścieżki zachowanej.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”Zachowany bufor stron nie poszerza powierzchni wejściowej; zmienia, kiedy bajty są serializowane, a nie to, co jest wczytywane. Jego odmowa połączenia z szyfrowaniem i podpisywaniem to właściwość bezpieczeństwa: uzupełnienie nigdy nie może zmienić podpisanych ani zaszyfrowanych bajtów po fakcie, ponieważ tych dwóch nie da się włączyć razem. Budżet bajtów ogranicza pamięć wobec wrogiego dokumentu.
Zgodność
Dział zatytułowany „Zgodność”| Twierdzenie | Norma | Klauzula |
|---|---|---|
| Writer serializuje ciało, strukturę odniesień krzyżowych i trailer w momencie zapisu. | ISO 32000-2 | §7.5 |
To podglądowa zdolność. NextPDF odmawia bufora uzupełniania dla dokumentów podpisanych, tagowanych, PDF/A, zlinearyzowanych, zaszyfrowanych i ze strumieniami obiektów, więc nie wysuwa twierdzenia o zgodności dla tych profili przez tę ścieżkę. Nie odtwarza się żadnego tekstu normatywnego.
Adapter Compat (TCPDF)
Dział zatytułowany „Adapter Compat (TCPDF)”Adapter zgodności TCPDF udostępnia tę zdolność jako rozszerzenie konstruktora.
Skonstruuj adapter z retainedPageBuffer: true, a wtedy wywołanie setPage()
lub lastPage() celujące we wcześniejszą stronę deleguje do uzupełniania w
rdzeniu, zamiast zgłaszać strumieniowy UnsupportedFeatureException. Ten
argument konstruktora to rozszerzenie NextPDF, a nie odpowiednik starego TCPDF
— stary TCPDF nie ma takiej flagi. Obowiązują te same odmowy fail-closed. Po
szczegóły po stronie adaptera zajrzyj na stronę zachowanego bufora stron adaptera
compat.