Migrer de Dompdf vers NextPDF
En un coup d’œil
Section intitulée « En un coup d’œil »Ce guide t’accompagne dans la migration d’une base de code reposant sur Dompdf vers le pipeline Html de NextPDF. Dompdf et NextPDF suivent le même schéma — charger du HTML, restituer, émettre un PDF — donc la plupart des sites d’appel se transposent mécaniquement. Le vrai travail consiste à établir la table de correspondance des options et à gérer les écarts de prise en charge CSS. NextPDF et Dompdf sont des moteurs indépendants : une mise en page produite par Dompdf est donc compatible avec le résultat de NextPDF, sans lui être identique à l’octet près. Ce guide couvre la correspondance des verbes, la correspondance des clés d’options, les différences de comportement et une séquence de migration sûre.
La prise en charge d’une fonctionnalité HTML/CSS par NextPDF ne garantit pas qu’un document Dompdf donné soit reproduit au pixel près. La matrice de prise en charge CSS fait autorité sur les fonctionnalités marquées Verified. Ce guide décrit le comportement ; il n’affirme aucune équivalence visuelle.
Installation
Section intitulée « Installation »composer require nextpdf/core:^3Garde dompdf/dompdf installé pendant la transition (la séquence de migration sûre fait cohabiter les deux jusqu’à ce que chaque site d’appel soit basculé), puis supprime-le une fois la bascule terminée.
Vue d’ensemble conceptuelle
Section intitulée « Vue d’ensemble conceptuelle »L’objet Dompdf fourni par Dompdf est une façade unique qui possède le DOM, la feuille de style, l’arbre de frames et le canevas. NextPDF sépare ces responsabilités : un NextPDF\Core\Document possède le modèle de page et la sortie, et une seule méthode, writeHtml(), pilote le pipeline HTML. Il n’y a pas d’étape séparée en deux phases « restituer puis émettre ». writeHtml() met le contenu en page au fur et à mesure qu’il l’écrit, et tu émets le document avec save(), output() ou getPdfData().
Le contenu de page que NextPDF écrit est du dessin de flux de contenu ISO 32000-2 (ISO 32000-2 §8, iso32000_2_sec8#x1.x3.p14). La géométrie de page que contrôle l’option de taille de papier correspond au MediaBox de l’objet page (ISO 32000-2 §7, iso32000_2_sec7#x1.x104.p10). Ce sont des fondamentaux du moteur, partagés par tout générateur conforme. Mais l’algorithme de mise en page qui transforme le CSS en ce contenu est propre à NextPDF, et il diffère de celui de Dompdf (voir Différences de comportement).
Surface de l’API
Section intitulée « Surface de l’API »L’API Html de NextPDF est documentée dans la référence du module Html (générée automatiquement à partir du PHPDoc). Les principaux points d’entrée utilisés ci-dessous sont : Document::createStandalone(), Document::writeHtml(string $html): static, Document::writeHtmlCell(...), Document::output(?string, OutputDestination), Document::save(string $path): void, Document::getPdfData(): string, et l’objet valeur NextPDF\Core\Config (pageSize, margins, fontsDirectory).
Correspondance des verbes de l’API
Section intitulée « Correspondance des verbes de l’API »Les noms de l’API publique de Dompdf ci-dessous sont vérifiés dans le dépôt public amont (dompdf/dompdf, master) — voir le fichier source _source-sidecar-upstream-api.md dans le dépôt. Aucun texte de documentation amont n’est reproduit.
| Dompdf | NextPDF | Notes |
|---|---|---|
new Dompdf($options) | Document::createStandalone($config) | Dompdf prend un objet Options ; NextPDF prend un NextPDF\Core\Config. Pour les workers de longue durée, utilise DocumentFactory plutôt que createStandalone(). |
$dompdf->loadHtml($html, $encoding) | $doc->writeHtml($html) | NextPDF traite l’entrée comme de l’UTF-8 ; transcode l’entrée non-UTF-8 avant l’appel plutôt que de passer un argument d’encodage. |
$dompdf->loadHtmlFile($file) | $doc->writeHtml(file_get_contents($file)) | NextPDF n’a pas de variante de chargement de fichier ; lis toi-même le fichier pour que la politique d’E/S reste dans ton code. |
$dompdf->setPaper($size, $orientation) | ConfigpageSize (un objet valeur PageSize) | Voir la table de correspondance des options. |
$dompdf->render() | (implicite) | NextPDF réalise la mise en page pendant writeHtml() ; il n’y a pas de phase de rendu séparée. Supprime l’appel à render(). |
$dompdf->output() | $doc->getPdfData() | Renvoie les octets du PDF. |
$dompdf->stream($name, $opts) | $doc->output($name, OutputDestination::Download) | NextPDF sépare la destination via l’énumération OutputDestination. |
$dompdf->setBasePath($p) / setProtocol() / setBaseHost() | (la résolution des ressources diffère) | NextPDF résout les ressources relatives par rapport à l’ensemble de travail du document, et non à un triplet base path/protocol — voir Différences de comportement. |
$dompdf->addInfo($label, $value) | $doc->setTitle() / setAuthor() / API de métadonnées | Les paires d’info libres de Dompdf correspondent aux setters de métadonnées typés (ISO 32000-2 §14 information du document, iso32000_2_sec14#x1.x5.p5). |
$dompdf->setHttpContext($ctx) | (pas d’équivalent) | NextPDF ne récupère pas de ressources distantes via un contexte de flux ; voir Non pris en charge / pas d’équivalent direct. |
Exemple de code — Démarrage rapide
Section intitulée « Exemple de code — Démarrage rapide »<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
// Dompdf:// $dompdf = new Dompdf();// $dompdf->loadHtml('<h1>Invoice</h1>');// $dompdf->setPaper('A4', 'portrait');// $dompdf->render();// file_put_contents('out.pdf', $dompdf->output());
// NextPDF — the createStandalone() default page size is A4 portrait:$doc = Document::createStandalone();$doc->setTitle('Invoice');$doc->addPage();$doc->writeHtml('<h1>Invoice</h1>');$doc->save(__DIR__ . '/out.pdf');
echo "Wrote out.pdf\n";Exemple de code — Production
Section intitulée « Exemple de code — Production »Cet exemple reflète examples/08-html-basic.php (le support exécutable de ce guide), avec une taille de papier explicite autre que celle par défaut et des marges. C’est l’équivalent d’un setPaper() de Dompdf plus une configuration de marges Options.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Contracts\OutputDestination;use NextPDF\Core\Config;use NextPDF\Core\Document;use NextPDF\ValueObjects\Margin;use NextPDF\ValueObjects\PageSize;
// Equivalent of: $dompdf->setPaper('letter','portrait') + margin options.// US Letter portrait = 612 x 792 pt.// Margin constructor order is (top, right, bottom, left) — all 0.5in here.$config = new Config( pageSize: new PageSize(612.0, 792.0, 'Letter'), margins: new Margin(36.0, 36.0, 36.0, 36.0), // top,right,bottom,left; 0.5in in points);
$doc = Document::createStandalone($config);$doc->setTitle('Quarterly Report');$doc->setAuthor('Finance');$doc->addPage();
$html = <<<'HTML'<h1 style="color:#1E3A8A;">Quarterly Report</h1><p>This report renders through the NextPDF Html pipeline. The CSS subset thatis <strong>Verified</strong> for production is the support-matrix authority,not this page.</p><table border="1"> <tr><th>Region</th><th>Total</th></tr> <tr><td>EMEA</td><td>1,204</td></tr></table>HTML;
$doc->writeHtml($html);
// Equivalent of $dompdf->stream('report.pdf'):$doc->output('report.pdf', OutputDestination::Download);Cas limites et pièges
Section intitulée « Cas limites et pièges »- Pas de rendu en deux phases. Le code Dompdf qui inspecte l’état entre
render()etoutput()(par exemple lire le nombre de pages) n’a pas d’analogue NextPDF à cet endroit précis du pipeline. Interroge plutôt le document aprèswriteHtml(). - Encodage. NextPDF abandonne le paramètre
$encodingde Dompdf : convertis l’entrée en UTF-8 avantwriteHtml(). Passer des octets Latin-1 produit du mojibake, pas une erreur. render()laissé en place. Un appel résiduel de style$dompdf->render()n’a pas de méthode NextPDF correspondante et provoquera une erreur fatale « undefined method ». Supprime-le pendant la bascule, ne le remplace pas par un stub.- PHP en ligne. L’option
enable_phpde Dompdf évalue<script type="text/php">. NextPDF n’a aucune exécution de PHP dans le document, par conception (c’est une surface d’injection). Déplace cette logique dans ton PHP avantwriteHtml(). - Résolution des ressources relatives. Dompdf résout
<img src>par rapport au triplet base path/protocol/host. NextPDF résout par rapport à l’ensemble de travail du document. Pendant la migration, passe des chemins absolus ou des URI de données pré-résolues pour éliminer la variable.
Performance
Section intitulée « Performance »writeHtml() met en page en une seule passe en flux (ADR-001). Aucun objet intermédiaire d’arbre de frames n’est conservé après la mise en page, donc la mémoire de pointe dépend de la taille du document plutôt que du nombre de nœuds du DOM. Le budget de performance pour l’exemple de ce guide est wall_ms: 2000, peak_mb: 128. Documents volumineux : découpe le HTML aux frontières des addPage() plutôt que de construire une seule chaîne de plusieurs mégaoctets.
Notes de sécurité
Section intitulée « Notes de sécurité »- Pas de récupération distante par contexte de flux. NextPDF n’implémente pas le parcours de récupération distante
setHttpContext()/enable_remotede Dompdf. Résous et valide les ressources distantes dans ton application, puis passe des octets ou des URI de données. Cela supprime la surface SSRF queenable_remotecomporte. - Pas d’exécution de code dans le document. L’absence d’un équivalent à
enable_phpest un durcissement délibéré, pas une lacune. - Les métadonnées de document que tu définis via les setters typés sont écrites dans le dictionnaire d’information ISO 32000-2 §14 / XMP (
iso32000_2_sec14#x1.x5.p5). N’y place pas de secrets.
Conformité
Section intitulée « Conformité »| Déclaration | Spécification | Clause | reference_id |
|---|---|---|---|
| Le contenu de page est du dessin de flux de contenu dans le modèle opaque/transparent. | ISO 32000-2 | §8 | |
| La taille de papier correspond à la boîte de délimitation de l’objet page. | ISO 32000-2 | §7 | |
| Les polices HTML sont écrites comme des programmes de police embedded/subset. | ISO 32000-2 | §9 | |
| Le traitement des espaces blancs et des retours à la ligne est propre au moteur. | CSS Text 3 | §6.5 |
NextPDF produit du contenu ISO 32000-2. Il n’affirme pas qu’un document Dompdf migré soit visuellement identique. Un changement de moteur de rendu exige toujours une nouvelle revue de la sortie.
Contexte commercial
Section intitulée « Contexte commercial »Non applicable. Le cœur couvre le parcours de migration HTML-vers-PDF décrit ici.
Voir aussi
Section intitulée « Voir aussi »Détail de la migration (sections requises R6)
Section intitulée « Détail de la migration (sections requises R6) »À qui cela s’adresse
Section intitulée « À qui cela s’adresse »Les équipes qui utilisent dompdf/dompdf pour du HTML-vers-PDF côté serveur et qui souhaitent passer au moteur NextPDF. Si tu n’appelles que loadHtml / setPaper / render / output, la correspondance des verbes couvre toute ta surface d’appel.
Périmètre
Section intitulée « Périmètre »Dans le périmètre : les verbes de la façade Dompdf, les clés Options, les attentes de parité des fonctionnalités CSS, la résolution des ressources, les métadonnées. Hors périmètre : les objets internes FrameTree/Canvas/Stylesheet de Dompdf (NextPDF n’a pas d’analogues publics — ne migre pas le code qui les manipule ; remplace-le par l’API publique).
Table de compatibilité
Section intitulée « Table de compatibilité »La couverture relève d’une behavioral compatibility, pas d’un shim drop-in. NextPDF n’a pas de shim de classe Dompdf (contrairement au parcours TCPDF — voir /migration/tcpdf-compat/). Tu réécris chaque site d’appel à l’aide de la correspondance des verbes. Les lignes Verified de la matrice de prise en charge CSS définissent à elles seules ce que tu peux attendre des fonctionnalités CSS. Ce guide ne reprend pas le statut par propriété.
Table de correspondance des options et de la configuration
Section intitulée « Table de correspondance des options et de la configuration »| Option Dompdf (clé / setter) | NextPDF | Notes |
|---|---|---|
default_paper_size / setDefaultPaperSize() ; setPaper($size,...) | Config->pageSize (objet valeur PageSize) | Les tailles nommées deviennent des dimensions en points explicites ; new PageSize(595.276, 841.890, 'A4') est la valeur par défaut de createStandalone(). |
default_paper_orientation / setDefaultPaperOrientation() | intervertir la PageSize width/height | NextPDF n’a pas d’indicateur d’orientation ; une page paysage est une PageSize dont la largeur > la hauteur. |
dpi / setDpi() | (ce n’est pas un réglage global) | NextPDF travaille en points PDF (1/72 de pouce) ; le dimensionnement des images se fait par image, pas via un multiplicateur DPI au niveau du document. Recalcule les tailles en pixels fixes en points. |
enable_remote / setIsRemoteEnabled() | (pas d’équivalent — par conception) | Résous les ressources distantes dans ton code ; voir Notes de sécurité. |
enable_html5_parser / setIsHtml5ParserEnabled() | (analyse toujours le HTML) | Pas de bascule ; l’analyseur est le pipeline. |
enable_php / setIsPhpEnabled() | (pas d’équivalent — par conception) | Le PHP dans le document n’est pas pris en charge ; sors la logique du template. |
font_dir / setFontDir() | Config->fontsDirectory | Une unique chaîne indiquant le répertoire de polices. |
chroot | (à résoudre dans l’application) | NextPDF ne prend pas d’option de cloisonnement du système de fichiers ; effectue la validation des chemins avant de passer les octets. |
default_font / setDefaultFont() | CSS font-family / police enregistrée | Définis la valeur par défaut via ta feuille de style de base ou l’enregistrement des polices, pas via une option globale. |
enable_font_subsetting / setIsFontSubsettingEnabled() | (sous-ensemble toujours) | NextPDF crée toujours un sous-ensemble des polices intégrées (ISO 32000-2 §9, iso32000_2_sec9#x1.x45.p7) ; il n’y a pas de « off » — un parcours Dompdf avec l’indicateur désactivé n’a pas d’équivalent et n’est pas nécessaire. |
Différences de comportement
Section intitulée « Différences de comportement »- Moteur de mise en page. Dompdf et NextPDF sont des implémentations de mise en page CSS indépendantes. L’effondrement des espaces blancs et les retours à la ligne sont spécifiés mais sensibles au moteur (CSS Text 3 §6.5,
css_text_3#x1.x6.x5.p20). Attends-toi à des différences de retour à la ligne et de pagination sur du texte dense. Recrée la référence des diffs visuels après la migration. - Jointure de rendu. Pas de frontière en deux phases
render()/output()(voir Cas limites). - Résolution des ressources. Base path/protocole/host contre ensemble de travail du document.
- Modèle DPI. Points contre multiplicateur DPI de Dompdf.
- Métadonnées. Paires
addInfo()libres contre setters typés (ISO 32000-2 §14,iso32000_2_sec14#x1.x5.p5).
Ce sont des différences de comportement documentées, pas des défauts dans l’un ou l’autre moteur.
Non pris en charge / pas d’équivalent direct
Section intitulée « Non pris en charge / pas d’équivalent direct »enable_php(PHP dans le document) — intentionnellement absent.setHttpContext()/enable_remoterécupération distante — intentionnellement absente.- Accès public à
FrameTree/Canvas/Stylesheet— pas d’analogue public. dpicomme multiplicateur global du document — non modélisé.
Le code qui dépend de ces éléments ne « migre » pas. Tu le supprimes ou le réexprimes dans le code de l’application selon les lignes ci-dessus.
Séquence de migration sûre
Section intitulée « Séquence de migration sûre »- Ajoute
nextpdf/coreà côté dedompdf/dompdf(ne supprime pas encore Dompdf). - Choisis un document à faible risque. Réécris son site d’appel avec la correspondance des verbes ; supprime l’appel à
render(). - Génère les deux PDF pour la même entrée et compare-les visuellement. Traite les différences comme attendues (moteurs indépendants) et décide de l’acceptation document par document.
- Convertis l’usage des options via la table de correspondance des options ; recalcule en points les tailles dérivées du DPI.
- Pré-résous les ressources distantes/relatives en chemins absolus ou en URI de données pour éliminer la variable de résolution.
- Répète document par document, du risque le plus faible au plus élevé. Garde les deux moteurs installés jusqu’à ce que le dernier site d’appel soit basculé.
- Supprime
dompdf/dompdfdecomposer.jsonseulement après la dernière bascule.
Tester la migration
Section intitulée « Tester la migration »- Prends un instantané de la sortie Dompdf de documents représentatifs avant de changer le code (entrées de référence, pas des octets de référence — les octets différeront).
- Pour chaque document migré, soumets la sortie NextPDF à ta propre vérification d’acceptation (diff visuel, assertions d’extraction de texte). Le comportement du pipeline HTML propre à NextPDF est couvert par
examples/08-html-basic.phpet la suite Html du cœurtests/. L’acceptation de ta migration est spécifique au document et c’est à toi de la valider. - Ajoute un test de régression par document migré pour qu’une future mise à jour du moteur soit détectée.
Preuves / traçabilité
Section intitulée « Preuves / traçabilité »Chaque déclaration de comportement NextPDF sur cette page est étayée par un test, un exemple, une signature source ou un ADR dans le dépôt — ou, lorsqu’il s’agit d’une propriété de format PDF, par les clauses ISO 32000-2 / CSS épinglées par RAG dans le citations: du frontmatter et la table de Conformité. Le comportement de dompdf est affirmé uniquement comme « moteur indépendant — attends-toi à des différences documentées ». Aucune parité n’est revendiquée sans preuve fournie par un artefact du dépôt.
| Déclaration de comportement NextPDF | Preuve dans le dépôt (chemin) |
|---|---|
createStandalone() : page par défaut A4 portrait (595.276 × 841.890 pt). | src/Core/Config.php (PageSize(595.276, 841.890, 'A4') par défaut) ; tests/Unit/Core/DocumentCreateStandaloneAndConfigWithersEdgeCaseTest.php (createStandaloneWithNullConfigBuildsDocumentWithA4Defaults). |
writeHtml() met en page en une seule passe en flux ; aucun DOM conservé après la mise en page. | docs/architecture/adr/ADR-001-stream-based-rendering-pipeline.md ; src/Core/Concerns/HasTextOutput.php (writeHtml()). |
writeHtml() crée automatiquement la première page quand il n’en existe aucune. | tests/Unit/Core/Concerns/DocumentTextOutputFontSubsettingAndBorderEdgeCaseTest.php (writeHtmlAutoCreatesFirstPageWhenNoPagesExist). |
output() / save() / getPdfData() sont les verbes d’émission (pas de deux phases render/output). | src/Core/Concerns/HasOutput.php (output(), save(), getPdfData()) ; tests/Unit/Core/Concerns/DocumentOutputDestinationDispatchTest.php. |
La destination de sortie est l’énumération NextPDF\Contracts\OutputDestination (Inline/Download/File/String). | src/Contracts/OutputDestination.php ; tests/Unit/Core/Concerns/DocumentOutputDestinationDispatchTest.php. |
| Les polices HTML sont toujours écrites comme des programmes embedded/subset. | tests/Unit/Core/Concerns/DocumentTextOutputFontSubsettingAndBorderEdgeCaseTest.php (recordUsedCharactersAffectsFontSubsetting) ; ISO 32000-2 §9 (citations: du frontmatter). |
Les setters de métadonnées typés (setTitle/setAuthor) remplacent addInfo() en forme libre. | src/Core/Concerns/HasMetadata.php (setTitle(), setAuthor()) ; tests/Unit/Core/Concerns/DocumentInfoMetadataSetterBaselineTest.php. |
| Pipeline HTML de bout en bout (le support exécutable de ce guide). | examples/08-html-basic.php ; suite tests/Unit/Html/ du cœur. |
| Les espaces blancs / retours à la ligne sont propres au moteur (écart de mise en page). | CSS Text 3 §6.5 (citations: du frontmatter + Conformité). |
Retour arrière
Section intitulée « Retour arrière »Comme les deux packages restent installés jusqu’à la bascule finale, le retour arrière d’un site d’appel non converti consiste à revenir au parcours Dompdf pour ce seul site d’appel. Après la bascule finale, le retour arrière consiste à restaurer dompdf/dompdf et le site d’appel précédent depuis le contrôle de version. Aucune migration de données n’est impliquée — uniquement du code.
Considérations de performance
Section intitulée « Considérations de performance »Voir Performance. Le modèle en une seule passe signifie que la migration n’introduit pas de coût de rétention de l’arbre de frames. Le principal changement de coût par document est la re-résolution anticipée des ressources (étape 5), que tu peux mettre en cache.
Pièges courants
Section intitulée « Pièges courants »- Laisser
render()en place (erreur fatale undefined method). - Passer des octets non-UTF-8 après avoir abandonné
$encoding(mojibake silencieux). - S’attendre à une sortie identique à l’octet près ou au pixel près (moteurs indépendants — ce guide ne revendique jamais un drop-in ni une compatibilité à 100 %).
- Compter sur les templates
enable_php(doit être refactorisé). - Traiter la matrice de prise en charge CSS comme indicative — elle fait autorité sur les fonctionnalités Verified et sur ce qu’il faut attendre.