Dzielenie długiego kodu HTML na strony
W skrócie
Dział zatytułowany „W skrócie”Użyj automatycznych podziałów stron, aby rozłożyć długą treść na wiele stron. Dodaj konspekt, żeby czytelnicy mogli przechodzić między sekcjami. Ten przepis opiera się na examples/12-bookmarks-and-toc.php.
Instalacja
Dział zatytułowany „Instalacja”composer require nextpdf/core:^3Użyj tego ograniczenia wersji dla pakietu nextpdf/core. Przykład działa w PHP 8.4.
Przegląd koncepcyjny
Dział zatytułowany „Przegląd koncepcyjny”setAutoPageBreak(true, $margin) nakazuje silnikowi rozpocząć nową stronę, zanim treść przekroczy próg dolnego marginesu. Silnik dzieli na tej granicy długi tekst zapisywany przez multiCell() lub writeHtml(). Moduł fragmentacji Cascading Style Sheets (CSS) (css_break_3) ma w macierzy wsparcia ocenę Verified. Stanowi on podstawę działania podziałów w potoku Hypertext Markup Language (HTML).
bookmark($title, $level) dodaje pozycję konspektu w bieżącym położeniu. Pozycja konspektu w formacie Portable Document Format (PDF) wiąże miejsce docelowe, dzięki czemu czytelnicy mogą przejść bezpośrednio do strony (ISO 32000-2). Silnik zapisuje to miejsce docelowe jako wpis Dest pozycji (ISO 32000-2). Użyj argumentu level, aby zagnieżdżać pozycje w hierarchicznym spisie treści na pasku bocznym czytnika.
Potok pozostaje jednoprzebiegowy (ADR-001). Silnik decyduje o paginacji podczas emisji strumienia, bez zachowywania drzewa układu.
Powierzchnia API
Dział zatytułowany „Powierzchnia API”setAutoPageBreak(bool $enabled, float $margin = 20): static—NextPDF\Core\Concerns\HasPages.bookmark(string $title, int $level = 0, float $y = -1): static—NextPDF\Core\Concerns\HasNavigation.multiCell(...)/writeHtml(string $html): static—NextPDF\Core\Concerns\HasTextOutput.
Pełna tabela PHPDoc jest generowana z kodu źródłowego.
Przykład kodu — szybki start
Dział zatytułowany „Przykład kodu — szybki start”<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setAutoPageBreak(true, margin: 25);$doc->addPage();$doc->bookmark('Section 1', level: 0);$doc->setFont('helvetica', '', 11);
for ($i = 1; $i <= 80; $i++) { $doc->multiCell(0, 7, "Paragraph {$i} of a long flowing document.");}
$doc->save(__DIR__ . '/out.pdf');Przykład kodu — produkcja
Dział zatytułowany „Przykład kodu — produkcja”Ten samodzielny przykład działa w środowisku testowym. Buduje dokument złożony z wielu rozdziałów, z zagnieżdżonym konspektem i automatycznymi podziałami stron, oraz odzwierciedla examples/12-bookmarks-and-toc.php.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Bookmarks and Navigation');$doc->setPrintHeader(false);$doc->setPrintFooter(false);$doc->setAutoPageBreak(true, margin: 25);
$chapters = [ 'Chapter 1: Introduction' => ['What is NextPDF?', 'Key Features'], 'Chapter 2: Getting Started' => ['Installation', 'Your First PDF'], 'Chapter 3: Advanced Topics' => ['Worker-safe Architecture', 'Streaming Output'],];
$body = 'NextPDF is a modern PDF 2.0 library for PHP. This paragraph is ' . 'repeated so the content overflows the page and the engine inserts ' . 'an automatic page break at the bottom-margin threshold.';
foreach ($chapters as $chapter => $sections) { $doc->addPage(); $doc->bookmark($chapter, level: 0); $doc->setFont('helvetica', 'B', 18); $doc->cell(0, 12, $chapter, newLine: true); $doc->ln(3);
foreach ($sections as $section) { $doc->bookmark($section, level: 1); $doc->setFont('helvetica', 'B', 14); $doc->cell(0, 10, $section, newLine: true); $doc->setFont('helvetica', '', 11); for ($i = 0; $i < 12; $i++) { $doc->multiCell(0, 7, $body); } $doc->ln(4); }}
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');$doc->save($out !== false ? $out : __DIR__ . '/paginate-long-html.pdf');
echo "Wrote paginate-long-html.pdf\n";Oczekiwane standardowe wyjście (STDOUT):
Wrote paginate-long-html.pdfPrzypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”- Wyłączenie i zapomnienie. Gdy automatyczny podział strony jest wyłączony, silnik przycina treść wykraczającą poza dolny margines, zamiast rozkładać ją na kolejne strony. Włącz go ponownie przed długą treścią.
- Treść niepodzielna. Pojedynczy blok wyższy niż użyteczna wysokość strony może zgłosić wyjątek
UnsplittableContentException. Przyczyną może być bardzo wysoki wiersz tabeli albo duży obraz. Podziel treść źródłową. - Zakładka przed treścią. Wywołaj
bookmark()w miejscu, na które ma wskazywać cel. Umieść ją bezpośrednio przed następnym nagłówkiem, na żądanej stronie. - Nagłówek i stopka rezerwują miejsce. Nagłówek lub stopka wydruku zmniejsza użyteczną wysokość treści, a próg podziału to uwzględnia. Wyłączenie obu elementów, tak jak w tym przykładzie, zapewnia pełną wysokość treści.
- Zagnieżdżanie konspektu.
levelokreśla głębokość zagnieżdżenia. Element podrzędny na poziomielevel: 1musi następować po elemencie nadrzędnym na poziomielevel: 0. W przeciwnym razie czytnik spłaszczy drzewo konspektu.
Wydajność
Dział zatytułowany „Wydajność”Silnik decyduje o paginacji w jednym przebiegu emisji. Koszt jest liniowy względem długości treści, O(n). Budżet wynosi wall_ms: 2000, peak_mb: 96. Czas rzeczywisty jest nieco wyższy niż w przepisach jednostronicowych, ponieważ wielostronicowe odsyłacze (xref) i składanie konspektu zwiększają nakład pracy. Model strumieniowy utrzymuje ograniczone zużycie pamięci, a konspekt pozostaje małą, płaską listą.
Fragment macierzy wsparcia CSS (tylko wiersze Verified)
Dział zatytułowany „Fragment macierzy wsparcia CSS (tylko wiersze Verified)”Ta tabela odtwarza tylko wiersze Verified ze zweryfikowanej macierzy wsparcia CSS.
| Moduł W3C | Poziom | Status | Dowody |
|---|---|---|---|
CSS Fragmentation (css_break_3) | 3 | Verified | src/Html/Fragmentation/, tests/Unit/Html/PagedMedia/ |
CSS Table (css_tables_3) | 3 | Verified | src/Html/Table/ + wzorcowe pliki PDF |
CSS Cascading and Inheritance (css_cascade_3) | 3 | Verified | src/Html/Cascade/ |
Selektory nazwanych stron @page należą do CSS Paged Media. Zanim na nich polegniesz, sprawdź bieżącą ocenę tego modułu w macierzy.
Ograniczenia strumieniowania jednoprzebiegowego (ADR-001)
Dział zatytułowany „Ograniczenia strumieniowania jednoprzebiegowego (ADR-001)”Silnik emituje podziały stron w miarę przepływu strumienia. Ponieważ nie ma zachowanego drzewa, które można by ponownie rozłożyć, każda decyzja o podziale jest ostateczna. Niektóre treści, takie jak odsyłacz, potrzebują ostatecznego numeru strony po wykonaniu układu. Taka treść jest ograniczona, więc twórz ją z myślą o tym ograniczeniu.
Kontrakty warstw (ADR-010)
Dział zatytułowany „Kontrakty warstw (ADR-010)”Paginacja należy do kontrolera podziału stron, a nie do parsera. Parser nie emituje surowych operatorów przejścia między stronami; żąda podziału poprzez kontrakt kontrolera.
Budżet pamięci dla dużych dokumentów
Dział zatytułowany „Budżet pamięci dla dużych dokumentów”Model strumieniowy przechowuje bufor bieżącej strony oraz płaską listę konspektu, a nie wszystkie strony naraz. Bardzo długi dokument pozostaje w granicach pułapu ADR-020, ponieważ silnik opróżnia ukończone strony. Tabele i kontenery flex nadal podlegają ograniczeniu 5,000 węzłów na kontekst.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”Wrogi dokument nie może wymusić nieograniczonego zużycia pamięci. Limity elementów i zagnieżdżania (ADR-001) oraz budżet węzłów na kontekst (ADR-020) ograniczają nakład pracy. Sprawdzaj długość i strukturę długiej treści dostarczanej przez użytkownika. Silnik renderuje kontrolowany przez atakującego tytuł konspektu jako tekst i nigdy go nie interpretuje.
Zgodność
Dział zatytułowany „Zgodność”| Stwierdzenie | Specyfikacja | Klauzula | reference_id |
|---|---|---|---|
| Każda pozycja konspektu może być powiązana z miejscem docelowym, dzięki czemu użytkownik przechodzi bezpośrednio do niej. | ISO 32000-2 | iso32000_2_sec12#x1.x5.p4 | |
| Wpis Dest pozycji konspektu nazywa miejsce docelowe wyświetlane po aktywowaniu pozycji. | ISO 32000-2 | iso32000_2_sec12#x1.x11.p30 |
Ten przepis pokazuje, jak NextPDF rozkłada długą treść i buduje konspekt. Macierz wsparcia ocenia CSS Fragmentation jako Verified.
Kontekst komercyjny
Dział zatytułowany „Kontekst komercyjny”Nie dotyczy.