Lange HTML over meerdere pagina's pagineren
In het kort
Sectie met titel “In het kort”Gebruik automatische pagina-einden om lange inhoud over meerdere pagina’s te laten lopen. Voeg een overzicht toe, zodat lezers tussen secties kunnen springen. Dit recipe volgt examples/12-bookmarks-and-toc.php.
Installeren
Sectie met titel “Installeren”composer require nextpdf/core:^3Gebruik deze constraint voor het pakket nextpdf/core. Het voorbeeld draait op PHP 8.4.
Conceptueel overzicht
Sectie met titel “Conceptueel overzicht”setAutoPageBreak(true, $margin) instrueert de engine om een nieuwe pagina te beginnen voordat de inhoud de ondermargedrempel overschrijdt. De engine fragmenteert lange tekst die met multiCell() of writeHtml() wordt geschreven op die grens. De Cascading Style Sheets (CSS) Fragmentation-module (css_break_3) heeft in de ondersteuningsmatrix de beoordeling Verified. Deze module ondersteunt het afbreekgedrag in de Hypertext Markup Language (HTML)-pijplijn.
bookmark($title, $level) voegt een overzichtsitem toe voor de huidige positie. Een overzichtsitem in Portable Document Format (PDF) koppelt een bestemming, zodat lezers rechtstreeks naar een pagina kunnen springen (ISO 32000-2). De engine schrijft die bestemming als de Dest-vermelding van het item (ISO 32000-2). Gebruik het argument level om items te nesten in een hiërarchische inhoudsopgave in de zijbalk van de viewer.
De pijplijn blijft single-pass (ADR-001). De engine bepaalt de paginering tijdens het uitzenden van de stream, zonder bewaarde lay-outboom.
API-oppervlak
Sectie met titel “API-oppervlak”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.
De volledige PHPDoc-tabel wordt gegenereerd vanuit de broncode.
Codevoorbeeld — snelstart
Sectie met titel “Codevoorbeeld — snelstart”<?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');Codevoorbeeld — productie
Sectie met titel “Codevoorbeeld — productie”Dit zelfstandige voorbeeld draait in de harness. Het bouwt een document met meerdere hoofdstukken, een geneste overzichtsstructuur en automatische pagina-einden, en weerspiegelt 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";Verwachte standaarduitvoer (STDOUT):
Wrote paginate-long-html.pdfRandgevallen en valkuilen
Sectie met titel “Randgevallen en valkuilen”- Uitschakelen en vergeten. Wanneer het automatische pagina-einde is uitgeschakeld, kapt de engine inhoud voorbij de ondermarge af in plaats van deze door te laten lopen. Schakel het opnieuw in vóór lange inhoud.
- Niet-splitsbare inhoud. Eén enkel blok dat hoger is dan de bruikbare paginahoogte kan een
UnsplittableContentExceptionveroorzaken. Dat kan gebeuren bij een zeer hoge tabelrij of grote afbeelding. Splits de broninhoud. - Bladwijzer vóór inhoud. Roep
bookmark()aan op de positie waar je wilt dat de bestemming naar verwijst. Plaats het direct vóór de volgende kop, op de gewenste pagina. - Kop- en voettekst reserveren ruimte. Een kop- of voettekst verkleint de bruikbare inhoudshoogte, en de afbreekdrempel houdt daar rekening mee. Door beide uit te schakelen, zoals dit voorbeeld doet, beschik je over de volledige hoogte van het tekstvlak.
- Nesting van het overzicht.
levelis de nestingdiepte. Een onderliggend item oplevel: 1moet volgen op een bovenliggend item oplevel: 0. Anders vlakt de viewer de overzichtsstructuur af.
Prestaties
Sectie met titel “Prestaties”De engine bepaalt de paginering in één emissiedoorloop. De kosten zijn lineair in de lengte van de inhoud, O(n). Het budget is wall_ms: 2000, peak_mb: 96. De doorlooptijd ligt iets hoger dan bij recipes van één pagina, omdat de cross-reference (xref) over meerdere pagina’s en het samenstellen van het overzicht extra werk met zich meebrengen. Het streamingmodel houdt het geheugengebruik begrensd, en het overzicht blijft een kleine vlakke lijst.
Fragment uit de CSS-ondersteuningsmatrix (alleen Verified-rijen)
Sectie met titel “Fragment uit de CSS-ondersteuningsmatrix (alleen Verified-rijen)”Deze tabel geeft alleen de Verified-rijen weer uit de CSS-ondersteuningsmatrix waarvan de juistheid is gecontroleerd.
| W3C-module | Niveau | Status | Bewijs |
|---|---|---|---|
CSS Fragmentation (css_break_3) | 3 | Verified | src/Html/Fragmentation/, tests/Unit/Html/PagedMedia/ |
CSS Table (css_tables_3) | 3 | Verified | src/Html/Table/ + golden-PDF’s |
CSS Cascading and Inheritance (css_cascade_3) | 3 | Verified | src/Html/Cascade/ |
@page-selectors voor benoemde pagina’s behoren tot CSS Paged Media. Raadpleeg de matrix voor de huidige beoordeling van die module voordat je erop vertrouwt.
Beperkingen van single-pass streaming (ADR-001)
Sectie met titel “Beperkingen van single-pass streaming (ADR-001)”De engine zendt pagina-einden uit terwijl de stream loopt. Omdat er geen bewaarde boom is die opnieuw kan worden doorlopen, is elke afbreekbeslissing definitief. Sommige inhoud, zoals een cross-reference, heeft het definitieve paginanummer pas nodig nadat de lay-out vastligt. Die inhoud is beperkt, dus houd bij het schrijven rekening met die beperking.
Laagcontracten (ADR-010)
Sectie met titel “Laagcontracten (ADR-010)”Paginering hoort bij de pagina-einde-controller, niet bij de parser. De parser zendt geen ruwe pagina-overgangsoperatoren uit; hij vraagt een afbreking aan via het controllercontract.
Geheugenbudget voor grote documenten
Sectie met titel “Geheugenbudget voor grote documenten”Het streamingmodel houdt de buffer van de huidige pagina en de vlakke overzichtslijst vast, niet alle pagina’s tegelijk. Een zeer lang document blijft binnen het ADR-020-plafond omdat de engine voltooide pagina’s leegmaakt. Tabellen en flex-containers blijven zich houden aan de grens van 5,000 nodes per context.
Beveiligingsnotities
Sectie met titel “Beveiligingsnotities”Een kwaadwillend document kan geen onbegrensd geheugengebruik afdwingen. De limieten voor elementen en nesting (ADR-001), samen met het node-budget per context (ADR-020), begrenzen het werk. Valideer de lengte en structuur van lange inhoud die gebruikers aanleveren. De engine geeft een door een aanvaller gecontroleerde overzichtstitel weer als tekst en interpreteert die nooit.
Conformiteit
Sectie met titel “Conformiteit”| Bewering | Specificatie | Clausule | reference_id |
|---|---|---|---|
| Elk overzichtsitem kan aan een bestemming worden gekoppeld zodat de gebruiker er rechtstreeks naartoe springt. | ISO 32000-2 | iso32000_2_sec12#x1.x5.p4 | |
| De Dest-vermelding van een overzichtsitem benoemt de bestemming die wordt weergegeven wanneer het item wordt geactiveerd. | ISO 32000-2 | iso32000_2_sec12#x1.x11.p30 |
Dit recipe laat zien hoe NextPDF lange inhoud over pagina’s laat lopen en een overzicht opbouwt. De ondersteuningsmatrix beoordeelt CSS Fragmentation als Verified.
Commerciële context
Sectie met titel “Commerciële context”Niet van toepassing.