HTML: renderingsubsysteem voor HTML+CSS naar PDF
In een oogopslag
Sectie met titel “In een oogopslag”Het HTML-subsysteem converteert HyperText Markup Language (HTML) en Cascading Style Sheets (CSS) in één voorwaartse passage naar Portable Document Format (PDF)-contentstreams. Het is het grootste subsysteem van de engine en ook het onderdeel met het hoogste risico, met 324 bestanden onder src/Html/.
Installatie
Sectie met titel “Installatie”composer require nextpdf/core:^3Conceptueel overzicht
Sectie met titel “Conceptueel overzicht”Het HTML-subsysteem is een single-pass streaming-renderer van HTML+CSS naar PDF. Het publieke oppervlak bestaat uit één methode: Document::writeHtml(). Intern tokeniseert HtmlParser de invoer, lost stijlen op, berekent de lay-out en schrijft PDF-operatoren weg in één voorwaartse passage, zonder een documentboom vast te houden.
Houd de reikwijdte scherp. Dit subsysteem is geen renderer met een behouden documentmodel. Het houdt geen elementgraaf bij, plaatst reeds weggeschreven content niet opnieuw in de lay-out en laat de invoer niet muteren nadat het parseren is begonnen. Het implementeert een samengestelde subset van CSS op vaste specificatieversies. Twee Architecture Decision Records (ADR’s) sturen dit aan. ADR-001 definieert het single-pass streaming-model en de bijbehorende limieten. ADR-010 definieert het vierlaags contract (CSS-parsing, stijlstatus, lay-out, paint), plus de aanvullingen voor paged media en meting.
HtmlParser is in het modulemanifest geclassificeerd als kritisch risico. Vijf bestanden hebben gedocumenteerde gevarenzone-annotaties: de HtmlParser-orchestrator (streaming-tokenizer, 1000+ regels code (LOC)), HtmlStyleState (100+ CSS-eigenschapsvelden met een stack-overervingsmodel), HtmlBlockHandler (blokdispatch gekoppeld aan de stijlstatus), FlexLayoutEngine (volledige flex-meting en -lay-out) en TableParser (colspan/rowspan-paginering over paginaovergangen heen). Behandel wijzigingen hier als werk in plan-modus.
Gebruik deze pagina als startpunt. Zie pipeline voor de fasevolgorde, css-resolver voor cascade en specificiteit, layer-contracts-adr010 voor de laaggrenzen en streaming-constraints-adr001 voor het model zonder behouden boom en de bijbehorende limieten.
Rechts-naar-links en bidirectionele tekst
Sectie met titel “Rechts-naar-links en bidirectionele tekst”writeHtml() geeft rechts-naar-links (RTL) content weer. Stel de CSS-eigenschap direction: rtl in op de body, een tabel of een willekeurig element. De engine bepaalt de visuele volgorde met het Unicode Bidirectional Algorithm (UAX #9) via de bidirectionele engine van de typografielaag — zie Typography voor de details van BidiEngine. Gemengde Latijnse, Arabische en numerieke content wordt correct geordend, en een getal na Arabisch behoudt zijn cijfers van links naar rechts.
Arabisch krijgt ook contextuele shaping: de engine selecteert de initiële, mediale, finale of geïsoleerde vorm van elke letter en past de Lam-Alef-ligatuur toe. Shaping vereist een geregistreerd lettertype waarvan de tekentoewijzing het Arabic Presentation Forms-B-blok dekt; een lettertype dat alleen Latijn dekt, inclusief de standard-14-lettertypen, kan geen Arabisch tekenen. In tabellen wordt elke cel afzonderlijk geherordend en geshaped en lijnt uit naar de start (rechter) rand onder direction: rtl. RTL geldt voor Arabisch, Hebreeuws, Perzisch en Urdu; Hebreeuws wordt geherordend maar niet geshaped.
Stel de richting in met de CSS-eigenschap direction — het HTML-dir-attribuut wordt er niet aan toegewezen. Horizontale uitlijning van niet-tabel-blok- en inline-tekst, en text-align: justify, worden nog niet toegepast. Zie voor een uitvoerbare Arabische factuur en de volledige lijst met huidige beperkingen Render right-to-left Arabic HTML.
API-oppervlak
Sectie met titel “API-oppervlak”| Symbool | Locatie | Rol |
|---|---|---|
Document::writeHtml(string $html): static | src/Core/Concerns/HasTextOutput.php | Publiek ingangspunt. Geeft HTML weer op de huidige cursor. |
Document::createStandalone(): self | src/Core/Document.php | Bouwt een standalone document. |
HtmlParser::parse(string $html): HtmlRenderResult | src/Html/HtmlParser.php | Interne orchestrator. |
HtmlRenderResult | src/Html/HtmlRenderResult.php | Onveranderlijk resultaat: stream, eindcursor en gebruikte lettertypen. |
DefaultHtmlSecurityPolicy | src/Html/DefaultHtmlSecurityPolicy.php | Standaardbeleid voor tags, attributen, CSS en Uniform Resource Locator (URL). |
HtmlSecurityPolicyInterface | src/Contracts/HtmlSecurityPolicyInterface.php | Beleidscontract voor aangepaste beleidsregels. |
Codevoorbeeld — Snelstart
Sectie met titel “Codevoorbeeld — Snelstart”Bron: examples/08-html-basic.php.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('HTML Basic');$doc->addPage();$doc->writeHtml('<h1 style="color:#1E3A8A;">HTML Rendering</h1><p>Direct to PDF.</p>');$doc->save(__DIR__ . '/output/08-html-basic.pdf');Codevoorbeeld — Productie
Sectie met titel “Codevoorbeeld — Productie”Dit voorbeeld toont een tabelrapport met een ingebed stijlblok, gebaseerd op examples/09-html-table.php.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;use NextPDF\Exception\HtmlParsingException;
function renderInventory(string $rowsHtml, string $out): void{ $doc = Document::createStandalone(); $doc->setTitle('Inventory'); $doc->addPage();
$html = '<style>table { width: 100%; } ' . 'th { background-color: #1E3A8A; color: #FFFFFF; }</style>' . '<table border="1" cellpadding="5">' . $rowsHtml . '</table>';
try { $doc->writeHtml($html); } catch (HtmlParsingException $e) { // Input cap, element cap (50,000), or nesting cap (100). Do not retry. throw $e; }
$doc->save($out);}Randgevallen en valkuilen
Sectie met titel “Randgevallen en valkuilen”- Samengestelde CSS-subset. De ondersteuning is per module vastgelegd. Raadpleeg de CSS-ondersteuningsmatrix voordat je op een eigenschap vertrouwt.
- Harde limieten werpen een uitzondering. Voor de limieten van 10 MB invoer,
50,000elementen en 100 nestingniveaus wordt telkens eenHtmlParsingExceptiongegooid. Zie streaming constraints. - Geen herindeling. De renderer schrijft de uitvoer eenmaal weg in documentvolgorde; latere stijlen kunnen eerdere uitvoer niet wijzigen.
:has()is afgeschermd achter de experimentele functiecss.has.- Subsysteem met kritisch risico. Vijf bestanden zijn gemarkeerd als gevarenzones. Gebruik plan-modus voor wijzigingen onder
src/Html/.
Single-pass streaming-beperkingen (ADR-001)
Sectie met titel “Single-pass streaming-beperkingen (ADR-001)”De renderer houdt geen documentboom bij en voert één voorwaartse passage uit. De limieten voor elementen, nesting en invoer zijn harde grenzen. Zie streaming constraints (ADR-001) voor alle details en het worker-safety-contract.
Laagcontracten (ADR-010)
Sectie met titel “Laagcontracten (ADR-010)”CSS-parsing, stijlstatus, lay-out en paint zijn ondergebracht in vier lagen met eenrichtingscontracten, plus aanvullingen voor paged media en meting. Zie layer contracts (ADR-010) voor alle details.
Geheugenbudget voor grote documenten
Sectie met titel “Geheugenbudget voor grote documenten”Het geheugen voor stijlstatus en cursor is O(nestingdiepte), niet O(aantal elementen). Het performance_budget per pagina is peak_mb: 64. De limiet van 50,000 elementen is het harde plafond; verdeel grotere invoer over meerdere aanroepen van writeHtml(). Zie streaming constraints voor details.
Prestaties
Sectie met titel “Prestaties”Het doorlopen is O(aantal tokens). Het bepalen van de kolombreedte van tabellen voegt per tabel een begrensde rijscan toe. De optionele :has()-voorscan voegt één begrensde passage over de tokenlijst toe. De prestatiebenchmark van de HTML-renderpipeline handhaaft een regressiegrens van 5% (samengevoegde wijzigingen, pull request (PR) #564). Het performance_budget per pagina (wall_ms: 1500, peak_mb: 64) is het operationele plafond.
Beveiligingsnotities
Sectie met titel “Beveiligingsnotities”DefaultHtmlSecurityPolicy handhaaft een allowlist van tags, attributen, CSS-eigenschappen en URL-schema’s, plus een invoerplafond van 10 MB en een nestingplafond van 100 niveaus, onafhankelijk van de parser. De allowlist van CSS-eigenschappen is het beveiligingsplafond. De runtime-ondersteuningstabel is een afzonderlijk capaciteitsplafond. Implementeer HtmlSecurityPolicyInterface om een striktere policy te leveren. DefaultExternalResourcePolicy regelt het ophalen van externe bronnen apart.
Voor waarden van href en image-src wijst de URL-allowlist ook paden af die met een backslash beginnen (\…) en Universal Naming Convention (UNC)-paden (\\host\share), naast de bestaande afwijzing van protocolrelatieve paden (//) en de allowlist die alleen http(s) of relatief toestaat. Backslashes worden voorafgaand aan de controle genormaliseerd naar forward slashes, zodat een Windows-include van een lokaal bestand met absoluut pad of een Server Message Block (SMB)-share-fetch niet door de tak „geen schema, dus relatief” kan glippen. Geen van beide paden heeft een Uniform Resource Identifier (URI)-schema.
Fragment uit de CSS-ondersteuningsmatrix (alleen Verified-rijen)
Sectie met titel “Fragment uit de CSS-ondersteuningsmatrix (alleen Verified-rijen)”Deze pagina herhaalt de ondersteuning per eigenschap niet. De CSS-ondersteuningsmatrix is de enige autoriteit voor de geverifieerde modulestatus per World Wide Web Consortium (W3C), inclusief welke modules Verified zijn versus Claimed.
Conformiteit
Sectie met titel “Conformiteit”Het subsysteem implementeert een samengestelde CSS-subset op vaste specificatieversies. Gedragsmatige specificatiekoppelingen voor de cascade zijn gedocumenteerd met clausule- en chunk-identifiers in css-resolver. De conformiteitsstatus per module staat in de CSS-ondersteuningsmatrix.
Commerciële context
Sectie met titel “Commerciële context”Enterprise-mogelijkheid. Premium verbreedt de CSS-dekking (geavanceerd printen en aanvullende modules) op exact dezelfde single-pass pipeline. De architectuur, limieten en laagcontracten blijven in alle edities gelijk. Zie de CSS-ondersteuningsmatrix.