Migrer une base de code TCPDF 6.x vers NextPDF
Le paquet nextpdf/compat-legacy expose, par-dessus le moteur NextPDF, les noms de méthodes publiques, l’ordre des paramètres et les valeurs par défaut de TCPDF 6.x grâce à l’adaptateur NextPDF\Compat\Tcpdf\TCPDF. Migre dans cet ordre : bascule d’abord sur le moteur avec le plus petit changement possible, valide ce qui fonctionne déjà, active le mode strict pour recenser ce qui ne fonctionne pas, corrige les sites d’appel un par un, puis retire l’adaptateur au profit de l’API moderne. L’adaptateur est un échafaudage de migration, pas la destination.
Les prérequis à vérifier d’emblée :
- Le cœur NextPDF et
nextpdf/compat-legacysont installés. - Tu disposes d’une base de code TCPDF 6.x existante dotée d’une suite de tests. La suite de tests est ton filet de sécurité à chacune des étapes ci-dessous.
Ce document est un guide pratique. Pour connaître le comportement détaillé d’un appel TCPDF, méthode par méthode, consulte la page de couverture des méthodes. Pour la stratégie complète fichier par fichier, avec le code, consulte la page de migration amont. Les deux liens figurent dans la section Voir aussi.
Installation
Section intitulée « Installation »Installe l’adaptateur aux côtés du cœur. Ne supprime pas encore la bibliothèque TCPDF d’origine : conserver les deux te permet de comparer la sortie pendant la migration.
composer require nextpdf/compat-legacyAvant de modifier le moindre code, vérifie que la dépendance vers le moteur se résout (nextpdf/core ^3.0) et que la suite de tests s’exécute toujours.
Vue d’ensemble conceptuelle
Section intitulée « Vue d’ensemble conceptuelle »L’adaptateur est une couche de compatibilité, pas un fork de TCPDF ni un clone identique à l’octet près. Parmi les quelque 120 méthodes publiques recensées de TCPDF 6.x, près de 94 correspondent directement à une opération NextPDF\Core\Document et conservent un comportement compatible pour les paramètres documentés. Une minorité bien délimitée accepte des paramètres hérités que le moteur ne prend pas en compte (ils sont ignorés silencieusement) ou ne produit aucune sortie (méthodes non implémentées ou non applicables). La matrice de couverture faisant autorité, vérifiée par les tests, se trouve dans le dépôt du paquet, à docs/TCPDF_COVERAGE.md. Si ce guide et cette matrice divergent, la matrice l’emporte.
Deux faits structurent toute la migration :
- Les octets de sortie diffèrent. Le moteur est une implémentation PDF 2.0 indépendante : les octets générés diffèrent donc de la sortie TCPDF, même lorsque le résultat visible paraît identique. Les tests qui s’appuient sur des octets PDF exacts doivent être recalibrés sur le contenu rendu ou sur des propriétés structurelles.
- Le mode strict est ton outil d’audit. Lorsque le mode strict est désactivé (le comportement par défaut), les méthodes qui ne peuvent pas reproduire le comportement de TCPDF basculent silencieusement vers un comportement dégradé. Lorsqu’il est activé, ces appels lèvent une
TcpdfNotImplementedExceptionqui indique précisément les paramètres ignorés et fournit une piste de migration. Exécute le mode strict dans une passe d’audit dédiée, jamais en production.
L’adaptateur expose aussi le document du moteur encapsulé via getDocument(), qui renvoie le NextPDF\Core\Document. C’est la voie de sortie : migre les sites d’appel vers l’API moderne un par un jusqu’à pouvoir supprimer l’adaptateur.
Surface de l’API
Section intitulée « Surface de l’API »| Préoccupation | Surface |
|---|---|
| Construire | new NextPDF\Compat\Tcpdf\TCPDF('P', 'mm', 'A4') |
| Alias globaux optionnels | NextPDF\Compat\Tcpdf\LegacyBootstrap::enableAliases() |
| Activer l’audit | TCPDF::setStrictMode(true) |
| Exception d’audit | NextPDF\Compat\Tcpdf\Exception\TcpdfNotImplementedException |
| Échappatoire vers l’API moderne | TCPDF::getDocument(): NextPDF\Core\Document |
| Sortie | TCPDF::Output(string $name, string $dest) — S, F, E, I, D |
LegacyBootstrap::enableAliases() est idempotente. Elle enregistre \TCPDF, \TCPDF_STATIC, \TCPDF_FONTS, \TCPDF_COLORS, et \TCPDF_IMAGES uniquement si ces classes n’existent pas déjà. La couverture complète, méthode par méthode, et le comportement de la destination de sortie figurent sur les pages de couverture des méthodes et de démarrage rapide liées dans la section Voir aussi.
Exemple de code — Démarrage rapide
Section intitulée « Exemple de code — Démarrage rapide »Change l’import, conserve les appels de style TCPDF et produis un PDF.
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\TCPDF;
$pdf = new TCPDF('P', 'mm', 'A4');$pdf->SetCreator('Quickstart');$pdf->SetTitle('First Document');$pdf->SetFont('helvetica', '', 12);$pdf->AddPage();$pdf->Cell(0, 10, 'Hello from the NextPDF engine', 1, 1, 'C');
$pdf->Output(__DIR__ . '/quickstart.pdf', 'F');Output($name, 'F') écrit le fichier et renvoie une chaîne vide. Contrairement au TCPDF historique, la méthode Output() de l’adaptateur n’écrit pas dans le tampon de sortie actif ; tu peux donc l’appeler en toute sécurité dans un worker de file d’attente ou un gestionnaire HTTP qui contrôle sa propre réponse.
Quand tu ne peux pas modifier les sites d’appel qui construisent new \TCPDF(...) dans l’espace de noms global, active une seule fois au démarrage les alias optionnels.
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\LegacyBootstrap;
LegacyBootstrap::enableAliases();
// Legacy code now resolves \TCPDF to the adapter:$pdf = new \TCPDF('P', 'mm', 'A4');$pdf->AddPage();$pdf->SetFont('helvetica', '', 12);$pdf->Cell(0, 10, 'Legacy call site, modern engine');$pdf->Output(__DIR__ . '/aliased.pdf', 'F');N’active pas les alias tant que la bibliothèque TCPDF d’origine reste autochargeable. L’alias est ignoré si une classe \TCPDF existe déjà ; tu pourrais donc continuer à utiliser le TCPDF historique sans t’en apercevoir. Pendant la migration, privilégie les imports fichier par fichier.
Exemple de code — Production
Section intitulée « Exemple de code — Production »L’étape de migration la plus sûre consiste à auditer en mode strict. Exécute, avec le mode strict activé, un chemin de production représentatif ou la suite de tests, et collecte chaque TcpdfNotImplementedException. Chaque exception est une tâche à traiter : elle nomme la méthode, les paramètres ignorés et une piste.
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\Exception\TcpdfNotImplementedException;use NextPDF\Compat\Tcpdf\TCPDF;
function renderInvoice(TCPDF $pdf): void{ // ... your existing rendering code, unchanged ...}
$pdf = new TCPDF('P', 'mm', 'A4');$pdf->setStrictMode(true);
try { renderInvoice($pdf); $pdf->Output(__DIR__ . '/audit.pdf', 'F');} catch (TcpdfNotImplementedException $exception) { // Each message names the method, the ignored parameters, and a hint. fwrite(STDERR, 'MIGRATION GAP: ' . $exception->getMessage() . "\n");}Pour chaque écart, choisis le correctif pertinent le moins coûteux : supprime un paramètre que tu n’as jamais utilisé, ou réexprime l’intention via l’API moderne avec getDocument(). L’échappatoire couvre tout ce que la surface TCPDF ne peut pas exprimer.
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\TCPDF;
$pdf = new TCPDF();$pdf->AddPage();
// Legacy path stays for the parts that already work:$pdf->SetFont('helvetica', '', 12);$pdf->Cell(0, 10, 'Header line', 0, 1);
// Modern path for what the TCPDF surface cannot express here —// for example a clickable image (the legacy Image() link parameter// is one of the silently ignored parameters):$document = $pdf->getDocument();$document->image('logo.png', 10, 30, 40, 0);$document->link(10, 30, 40, 20, 'https://example.com');Fais tourner le mode strict dans un job CI dédié, puis désactive-le et déploie le chemin de code audité. Garde un job CI périodique en mode strict pour détecter les régressions au fil de tes refactorisations.
Cas limites & pièges
Section intitulée « Cas limites & pièges »MultiCell()renvoie1,Write()renvoie0. Ce sont des valeurs de substitution pour la compatibilité, pas des valeurs calculées. Adapte tout code qui branche sa logique sur ces valeurs de retour.Error()lève une exception au lieu d’appelerdie(). L’adaptateur lève uneRuntimeException. Le code qui s’appuyait sur l’arrêt du processus doit intercepter l’exception.- Paramètres ignorés silencieusement. Des méthodes comme
Image(),writeHTML(),SetProtection()etBookmark()acceptent des paramètres hérités qui sont ignorés. Utilise le mode strict pour les repérer. Pour une image cliquable, dessine l’image, puis ajouteDocument::link()sur le même rectangle. - Méthodes non implémentées.
setSignature(),addEmptySignatureAppearance()etendPage()sont des no-op qui lèvent une exception en mode strict ;Open()est un no-op sûr qui ne lève jamais d’exception. SupprimeendPage()etOpen(). La signature nécessite une édition commerciale de NextPDF via l’API de signature moderne. - La version du PDF est figée.
setPDFVersion()ne peut pas cibler une version PDF plus ancienne ; la sortie est toujours en PDF 2.0.setUserRights()est dépréciée en PDF 2.0 et ignorée avec un avis. - Conflit d’alias. Si un élément se résout encore vers la classe TCPDF d’origine après que tu as supprimé
tecnickcom/tcpdf, c’est que le mécanisme de réserve des alias s’est appliqué : importe explicitement l’adaptateur sur ces sites d’appel.
Performance
Section intitulée « Performance »L’adaptateur délègue au moteur ; le coût de construction du document évolue avec le contenu, pas avec la couche de l’adaptateur. Comme la méthode Output() de l’adaptateur n’écrit pas dans le tampon de sortie, elle est sûre dans un worker de file d’attente : déporte la génération lourde écrite dans le style TCPDF hors du thread de requête, comme tu le ferais pour n’importe quelle génération NextPDF. Recalibrer les tests octet par octet pour les faire porter sur le contenu rendu est un coût ponctuel, et cela donne des tests qui survivent aux futures mises à niveau du moteur.
Notes de sécurité
Section intitulée « Notes de sécurité »- Chiffrement.
SetProtection()ignore les paramètres héritésmodeetpubkeys; le moteur utilise AES-256 avec le gestionnaire standard. Pour le chiffrement basé sur certificat, utilise le point d’entrée moderne de chiffrement à clé publique exposé sur l’adaptateur, pas les paramètres hérités. - La signature est restreinte. La prise en charge des signatures de base est une fonctionnalité d’édition commerciale, accessible via l’API de signature moderne avec un objet valeur de certificat ; la méthode héritée
setSignature()est un no-op. Ce guide ne formule aucune affirmation sur les profils de signature avec validation à long terme ou horodatage, quelle que soit l’édition. - Échoue explicitement pendant l’audit. Le mode strict rend visible la perte silencieuse de paramètres ; un appelant apprend ainsi quand son intention n’a pas été honorée. Traite les exceptions collectées comme la liste des tâches de migration, pas comme un comportement de production.
- N’écris jamais de bloc
catchvide. L’exemple d’audit intercepteTcpdfNotImplementedExceptionet écrit une tâche clairement définie.
La posture complète de chiffrement et de signature pendant la migration figure sur la page sécurité et exploitation de compat-legacy.
Conformité
Section intitulée « Conformité »Ce guide ne formule pas d’affirmation normative de conformité qui lui soit propre. L’adaptateur produit une sortie en PDF 2.0 (ISO 32000-2) et ne peut pas cibler une version plus ancienne. Ce comportement et la clause associée sont fixés sur la page amont de couverture des méthodes, qui consigne également le principe OWASP d’échec explicite derrière le mode strict et le cadrage de complétude fonctionnelle ISO/IEC 25023 de l’audit de couverture. Cette page du Cookbook en restitue l’usage et renvoie aux citations portées par la page amont.
Voir aussi
Section intitulée « Voir aussi »- Renvoyer un PDF généré depuis un contrôleur — renvoie la sortie de l’adaptateur comme réponse HTTP.
- Démarrage rapide de compat-legacy — premier document, destinations de sortie et échappatoire.
- Couverture des méthodes TCPDF — l’audit méthode par méthode et la matrice faisant autorité.
- Migrer de TCPDF 6.x vers NextPDF — la stratégie complète en six étapes avec le code.