Migrer de mPDF vers NextPDF
Ce guide t’aide à migrer une base de code reposant sur mPDF vers le cœur de NextPDF. Le verbe central de mPDF est WriteHTML(), qui correspond directement à Document::writeHtml(). L’essentiel du travail consiste à faire correspondre le tableau de configuration du constructeur (mPDF configure tout via un unique tableau associatif passé à new Mpdf([...])) et à traiter l’écart de gestion des polices. NextPDF et mPDF sont des moteurs indépendants : un document migré est donc compatible avec la sortie mPDF, sans lui être identique octet pour octet. Ce guide couvre la table des verbes, la table de correspondance du tableau de configuration, l’écart de gestion des polices, l’écart de prise en charge CSS, les différences de comportement et une séquence de migration sûre.
La matrice de prise en charge CSS fait autorité pour les fonctionnalités HTML/CSS vérifiées. Ce guide décrit un comportement ; il n’affirme aucune équivalence visuelle avec mPDF.
Installation
Section intitulée « Installation »composer require nextpdf/core:^3Garde mpdf/mpdf installé pendant la transition. Supprime-le après la bascule finale (voir la séquence de migration sûre).
Vue d’ensemble conceptuelle
Section intitulée « Vue d’ensemble conceptuelle »L’objet Mpdf de mPDF est une grande façade unique. Il est configuré par un tableau de constructeur, puis piloté par WriteHTML() et par les verbes de pagination (AddPage, SetHTMLHeader, SetHTMLFooter). NextPDF sépare la configuration dans l’objet valeur immuable NextPDF\Core\Config et pilote le contenu avec Document::writeHtml(). Aucune chaîne de « mode » n’est transmise au constructeur. NextPDF analyse le HTML que tu passes, puis émet le document avec save(), output() ou getPdfData().
Polices : mPDF fournit un répertoire de polices, une table fontdata et un ensemble de repli de « polices de base ». NextPDF résout les polices via un unique répertoire de polices et la correspondance CSS font-family, et embarque toujours les polices sous forme de sous-ensembles (ISO 32000-2 §9, iso32000_2_sec9#x1.x45.p7). Le matching/fallback des polices est propre à chaque moteur (CSS Fonts 4 §5.5, css_fonts_4#x1.x5.x5.x1.p13) ; la substitution de glyphes peut donc varier. C’est le principal écart visible, traité dans l’écart de gestion des polices.
Surface de l’API
Section intitulée « Surface de l’API »L’API HTML de NextPDF correspond à la référence du module Html. Les points d’entrée principaux sont : Document::createStandalone(), Document::writeHtml(string $html): static, Document::writeHtmlCell(...), Document::addPage(), Document::output(?string, OutputDestination), Document::save(string $path): void, Document::getPdfData(): string et l’objet valeur NextPDF\Core\Config.
Correspondance des verbes de l’API
Section intitulée « Correspondance des verbes de l’API »Les noms de méthodes publiques mPDF ci-dessous sont vérifiés à partir du dépôt public amont (mpdf/mpdf, development) — voir le sidecar de provenance _source-sidecar-upstream-api.md dans le dépôt. Aucun texte de documentation amont n’est reproduit.
| mPDF | NextPDF | Notes |
|---|---|---|
new Mpdf([...]) | Document::createStandalone($config) | Le tableau de configuration mPDF correspond à NextPDF\Core\Config ; voir la table de configuration. Utilise DocumentFactory pour les workers à longue durée de vie. |
$mpdf->WriteHTML($html) | $doc->writeHtml($html) | Correspondance directe. Le second argument $mode de mPDF (document complet, CSS seul ou élément) n’a aucun équivalent NextPDF — passe du HTML complet. |
$mpdf->WriteFixedPosHTML(...) | $doc->writeHtmlCell(...) | Région HTML positionnée et dimensionnée ; fais correspondre les arguments x/y/largeur/hauteur. |
$mpdf->AddPage(...) | $doc->addPage() | Les remplacements d’orientation/format/marge par appel de mPDF ne sont pas des arguments dans NextPDF ; modifie plutôt le modèle de document entre les appels. |
$mpdf->SetHTMLHeader($html) / SetHTMLFooter($html) | header/footer via l’API Layout | Les en-têtes HTML courants de mPDF correspondent au mécanisme header/footer de NextPDF, et non à du HTML en ligne en haut du corps. |
$mpdf->Output($name, $dest) | $doc->output($name, OutputDestination::…) | Les caractères de destination de mPDF (I/D/F/S) correspondent à l’énumération OutputDestination (Inline/Download/fichier via save()/chaîne via getPdfData()). |
$mpdf->Output('','S') | $doc->getPdfData() | Renvoie les octets. |
$mpdf->Output($path,'F') | $doc->save($path) | Écris vers un chemin de fichier. |
$mpdf->SetTitle($t) | $doc->setTitle($t) | Atterrit dans le dictionnaire d’informations / XMP d’ISO 32000-2 §14 (iso32000_2_sec14#x1.x5.p5). |
$mpdf->SetProtection($perms,...) | $doc->setEncryption(...) (API Security) | Les permissions reposent sur la coopération du lecteur ; ce n’est pas un contrôle d’accès — voir les notes de sécurité. |
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;
// mPDF:// $mpdf = new \Mpdf\Mpdf();// $mpdf->WriteHTML('<h1>Invoice</h1>');// $mpdf->Output('out.pdf', \Mpdf\Output\Destination::FILE);
// NextPDF — default page 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 s’aligne sur examples/04-text-and-fonts.php, le support exécutable des concepts de gestion des polices de ce guide. Il utilise une taille de page explicite, des marges et un corps de contenu qui met à l’épreuve la sélection des polices.
<?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: new Mpdf(['format'=>'A4','margin_left'=>20, ...]).// Margin constructor order is (top, right, bottom, left) — NOT L,R,T,B.$config = new Config( pageSize: new PageSize(595.276, 841.890, 'A4'), margins: new Margin(16.0, 20.0, 16.0, 20.0), // top,right,bottom,left in points fontsDirectory: __DIR__ . '/fonts',);
$doc = Document::createStandalone($config);$doc->setTitle('Quarterly Report');$doc->addPage();
$html = <<<'HTML'<h1 style="font-family:'DejaVu Sans';color:#1E3A8A;">Quarterly Report</h1><p>Body text resolves through CSS font-family matching against the configuredfonts directory. mPDF's fontdata map has no direct analogue — register thefamily via CSS and the fonts directory instead.</p>HTML;
$doc->writeHtml($html);
// Equivalent of $mpdf->Output('report.pdf', Destination::DOWNLOAD):$doc->output('report.pdf', OutputDestination::Download);Cas limites et pièges
Section intitulée « Cas limites et pièges »- Argument
$modesurWriteHTML. LeWriteHTML($html, $mode)de mPDF (2 = CSS seul, 1 = élément) n’a aucun équivalent. Intègre ton CSS directement dans le HTML que tu passes ; il n’existe aucune séquence « écrire le CSS puis écrire le corps ». - Remplacements par
AddPage. mPDF laisseAddPage()changer le format/orientation en cours de document via des arguments. NextPDFaddPage()ne prend aucun argument de ce genre ; les changements de taille du modèle passent par le document, pas par l’appel de page. - HTML d’en-tête/pied de page. Les en-têtes courants de mPDF sont des fragments HTML enregistrés séparément ; ne les insère pas directement dans le corps. Fais-les correspondre au mécanisme header/footer de NextPDF.
- Noms de polices. mPDF normalise les noms de polices via sa table
fontdata/core-font. NextPDF fait correspondre lefont-familyCSS au répertoire de polices ; un alias mPDF qui se résolvait silencieusement peut nécessiter une déclaration@font-face/family explicite. - Caractères de destination.
'I'/'D'/'F'/'S'ne sont pas acceptés ; utilise l’énumérationOutputDestinationousave()/getPdfData().
Performance
Section intitulée « Performance »writeHtml() fonctionne en une seule passe (ADR-001) ; le pic de mémoire suit la taille du document, pas un DOM conservé. Budget pour l’exemple de ce guide : wall_ms: 2000, peak_mb: 128. Pour les documents longs, pagine le contenu sur plusieurs addPage() plutôt qu’en une seule chaîne très longue. C’est le même conseil qui s’applique au découpage via $mode de mPDF, mais exprimé via le modèle de page.
Notes de sécurité
Section intitulée « Notes de sécurité »- Les permissions reposent sur la coopération du lecteur.
SetProtection()→setEncryption()assure la confidentialité, pas le contrôle d’accès : les bits de permission ISO dépendent d’un lecteur coopératif. Ne présente pas le chiffrement comme un contrôle d’accès aux utilisateurs. - Métadonnées.
SetTitle()et les informations du document atterrissent dans le dictionnaire d’informations / XMP d’ISO 32000-2 §14 (iso32000_2_sec14#x1.x5.p5) ; n’y stocke jamais de secrets. - NextPDF n’exécute pas de scripts intégrés au document ; aucune directive mPDF n’active cela ici.
Conformité
Section intitulée « Conformité »| Déclaration | Spécification | Article | reference_id |
|---|---|---|---|
| Les polices sont écrites en tant que programmes de police embedded/subset. | ISO 32000-2 | §9 | |
| Le format/margins de page correspondent à la boîte de délimitation de la page. | ISO 32000-2 | §7 | |
| Les métadonnées de titre / de protection atterrissent dans le dictionnaire d’informations / XMP. | ISO 32000-2 | §14 | |
| La correspondance / le repli des polices est propre à chaque moteur. | CSS Fonts 4 | §5.5 |
NextPDF produit du contenu ISO 32000-2 ; il n’affirme aucune identité visuelle avec mPDF. Un changement de moteur de rendu impose une nouvelle revue de la sortie.
Contexte commercial
Section intitulée « Contexte commercial »Sans objet. Le cœur couvre le chemin de migration mPDF 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 ça s’adresse
Section intitulée « À qui ça s’adresse »Les équipes qui utilisent mpdf/mpdf pour de la conversion HTML-vers-PDF côté serveur. Si ta surface est new Mpdf([...]) + WriteHTML + Output (+ header/footer en option), elle est couverte par la correspondance des verbes et la table de configuration.
Périmètre
Section intitulée « Périmètre »Dans le périmètre : le tableau de configuration du constructeur Mpdf, WriteHTML/Output/AddPage, les headers/footers, les polices, la protection, les métadonnées. Hors périmètre : les classes internes de mPDF et la surface des helpers QR/code-barres/filigrane (fais-les correspondre aux modules NextPDF correspondants — Barcode, Graphics — non traités ici).
Table de compatibilité
Section intitulée « Table de compatibilité »Compatibilité comportementale, pas un shim qui se substitue directement : il n’existe aucun shim de classe Mpdf. Chaque site d’appel est réécrit. Pour les fonctionnalités CSS, l’attendu correspond aux lignes vérifiées de la matrice de prise en charge CSS.
Table de correspondance du tableau de configuration du constructeur
Section intitulée « Table de correspondance du tableau de configuration du constructeur »Les clés de configuration mPDF sont confirmées par rapport au dépôt public amont (mpdf/mpdf, development). Aucun texte de documentation amont n’est reproduit.
| Clé de configuration mPDF | NextPDF | Notes |
|---|---|---|
mode | (aucun équivalent) | La chaîne de mode de mPDF ('utf-8', 'c', '+aCJK', …) sélectionne le comportement font/script. NextPDF est toujours en Unicode ; le CJK est géré par la sélection des polices, pas par un mode. Supprime la clé. |
format | Config->pageSize (objet valeur PageSize) | Les formats nommés deviennent des dimensions explicites en points ; les tableaux [w,h] correspondent à un PageSize. |
orientation | permute la PageSize width/height | Aucun indicateur d’orientation ; paysage = largeur > hauteur. |
default_font_size | font-size de base CSS | À définir via ta feuille de style de base, pas via une clé de constructeur. |
default_font | CSS font-family / police enregistrée | Définis la famille par défaut via le CSS / l’enregistrement des polices. |
margin_left / margin_right / margin_top / margin_bottom | Config->margins (objet valeur Margin) en points | Un unique objet valeur Margin ; l’ordre de son constructeur est Margin(top, right, bottom, left) (vérifie par rapport à src/ValueObjects/Margin.php), pas par rapport à l’ordre des clés mPDF. |
margin_header / margin_footer | décalage d’header/footer via l’API Layout | À faire correspondre à la configuration NextPDF header/footer, pas à des clés de constructeur. |
Écart de gestion des polices
Section intitulée « Écart de gestion des polices »- Répertoire de polices unique. La liste des répertoires de polices de mPDF + la table
fontdata+ le repli des polices de base se ramènent àConfig->fontsDirectoryplus la correspondance CSSfont-family. - Toujours en sous-ensemble. NextPDF embarque toujours les polices sous forme de sous-ensembles (ISO 32000-2 §9,
iso32000_2_sec9#x1.x45.p7) ; les indicateurs de sous-ensemble de mPDF n’ont aucun équivalent et ne sont pas nécessaires. - La correspondance est propre à chaque moteur. Le matching/fallback des polices diffère selon le moteur (CSS Fonts 4 §5.5,
css_fonts_4#x1.x5.x5.x1.p13) ; un alias de police mPDF peut nécessiter un@font-faceexplicite ou un nom de famille exact. Re-baseline le rendu des glyphes après la migration ; les différences de substitution sont attendues, ce ne sont pas des défauts.
Différences de comportement
Section intitulée « Différences de comportement »- Substitution de polices (voir ci-dessus) — le principal écart visible.
- Pas de
$modesurWriteHTML— passe du HTML complet avec du CSS en ligne. - Pas de remplacement de format par
AddPage— les changements de taille du modèle passent par le document. - Les permissions reposent sur la coopération du lecteur (voir les notes de sécurité).
- Moteur de mise en page indépendant — le retour à la ligne / la pagination peuvent différer sur du contenu dense ; re-baseline les diffs visuels.
Ce sont des différences de comportement documentées, pas des défauts dans l’un ou l’autre moteur.
Non pris en charge / sans équivalent direct
Section intitulée « Non pris en charge / sans équivalent direct »- Chaîne de constructeur
mode— non modélisée (toujours en Unicode). - Arguments de
AddPage()format/orientation/marge par page — ne sont pas des arguments dans NextPDF. - Table
fontdatade mPDF — remplacée par le répertoire de polices + la correspondance CSS. - Les caractères de destination
'I'/'D'/'F'/'S'de mPDF — remplacés par l’énumérationOutputDestination+save()/getPdfData().
Séquence de migration sûre
Section intitulée « Séquence de migration sûre »- Ajoute
nextpdf/coreà côté dempdf/mpdf(garde mPDF pour l’instant). - Choisis un document à faible risque. Convertis
new Mpdf([...])via la table de configuration etWriteHTML/Outputvia la table des verbes. - Enregistre les polices que le document utilise dans
Config->fontsDirectoryet ajoute des déclarations@font-face/family explicites pour tout alias mPDF. - Génère les deux PDF pour la même entrée ; compare-les visuellement. Les différences (substitution de polices, retour à la ligne) sont attendues pour des moteurs indépendants — accepte-les document par document.
- Fais correspondre tout HTML d’header/footer au mécanisme d’NextPDF header/footer.
- Répète l’opération document par document, en commençant par les moins risqués ; garde mPDF installé jusqu’à la dernière bascule.
- Supprime
mpdf/mpdfdecomposer.jsonaprès la dernière bascule.
Tester la migration
Section intitulée « Tester la migration »- Capture la sortie mPDF de documents représentatifs avant de changer le code (entrées de référence ; les octets différeront).
- Pour chaque document migré, valide avec ta propre vérification d’acceptation (diff visuel + extraction de texte). Le comportement des polices/du HTML de NextPDF est mis à l’épreuve par
examples/04-text-and-fonts.phpetexamples/08-html-basic.php, ainsi que par les suites Html/Font danstests/du cœur. L’acceptation de la migration est propre à chaque document et relève de ta responsabilité. - Ajoute un test de non-régression par document migré.
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é du format PDF, par les articles ISO 32000-2 / CSS épinglés via RAG dans la citations: du front-matter et la table Conformité. Le comportement mPDF est uniquement affirmé comme « moteur indépendant — attends-toi à des différences documentées » ; aucune parité n’est revendiquée sans preuve par un artefact du dépôt.
| Affirmation de comportement NextPDF | Preuve dans le dépôt (chemin) |
|---|---|
WriteHTML() correspond directement à Document::writeHtml(string $html): static. | src/Core/Concerns/HasTextOutput.php (writeHtml()) ; examples/08-html-basic.php. |
WriteFixedPosHTML(...) correspond à writeHtmlCell(...). | src/Core/Concerns/HasTextOutput.php (writeHtmlCell()). |
La page par défaut de createStandalone() est A4 portrait (595.276 × 841.890 pt). | src/Core/Config.php (PageSize par défaut) ; tests/Unit/Core/DocumentCreateStandaloneAndConfigWithersEdgeCaseTest.php. |
Ordre du constructeur de Margin : (top, right, bottom, left). | src/ValueObjects/Margin.php (ordre des propriétés promues). |
La destination de sortie est l’énumération NextPDF\Contracts\OutputDestination ; 'I'/'D'/'F'/'S' ne sont pas acceptés. | src/Contracts/OutputDestination.php (cas Inline/Download/File/String) ; tests/Unit/Core/Concerns/DocumentOutputDestinationDispatchTest.php. |
Output('','S') → getPdfData() ; Output($path,'F') → save($path). | src/Core/Concerns/HasOutput.php (getPdfData(), save(), output()). |
SetProtection() correspond à setEncryption(...) ; les permissions reposent sur la coopération du lecteur. | src/Core/Concerns/HasSecurity.php (setEncryption()) ; ISO 32000-2 §14 (citations: du front-matter). |
SetTitle() → setTitle() ; les métadonnées atterrissent dans le dictionnaire d’informations / XMP. | src/Core/Concerns/HasMetadata.php (setTitle()) ; tests/Unit/Core/Concerns/DocumentInfoMetadataSetterBaselineTest.php ; ISO 32000-2 §14 (citations: du front-matter). |
| Les polices sont toujours embarquées sous forme de programmes en sous-ensemble. | tests/Unit/Core/Concerns/DocumentTextOutputFontSubsettingAndBorderEdgeCaseTest.php ; examples/04-text-and-fonts.php ; ISO 32000-2 §9 (citations: du front-matter). |
| La correspondance / le repli des polices est propre à chaque moteur (écart de substitution). | CSS Fonts 4 §5.5 (citations: du front-matter + Conformité). |
writeHtml() fonctionne en une seule passe ; le pic de mémoire suit la taille du document. | docs/architecture/adr/ADR-001-stream-based-rendering-pipeline.md. |
Retour arrière
Section intitulée « Retour arrière »Les deux packages restent installés jusqu’à la bascule finale ; le retour arrière par site d’appel consiste donc à revenir au chemin mPDF pour ce site d’appel. Après la bascule finale, le retour arrière consiste à restaurer mpdf/mpdf et le code précédent depuis le contrôle de version. Aucune migration de données n’est en jeu.
Considérations de performance
Section intitulée « Considérations de performance »Voir Performance. Le modèle en une seule passe supprime le coût du tampon conservé de mPDF. Le nouveau coût par document est la résolution anticipée des polices (étape 3), qui peut être mise en cache via le répertoire de polices.
Pièges courants
Section intitulée « Pièges courants »- Garder la clé
modeet en attendre un comportement CJK (elle est supprimée ; le CJK relève de la sélection des polices). - Passer
WriteHTML($html, 2)(mode CSS seul) — intègre plutôt le CSS en ligne. - Coller du HTML d’header/footer dans le corps.
- S’attendre à la même police pour un alias mPDF sans famille explicite.
- S’attendre à une sortie byte/pixel-identical (moteurs indépendants — ce guide ne revendique jamais ni substitution directe ni compatibilité à 100 %).
- Traiter la matrice de prise en charge CSS comme indicative — elle fait autorité pour les fonctionnalités vérifiées.