Migrare da TCPDF 6.x a NextPDF
In breve
Sezione intitolata “In breve”La migrazione segue una sequenza precisa. Passare prima al motore NextPDF, con la modifica più piccola possibile. Verificare ciò che funziona già. Sottoporre ad audit ciò che non funziona. Correggere i punti di chiamata uno alla volta. Solo dopo rimuovere l’adattatore. Il livello di compatibilità supporta i passi dal due al quattro; non è la destinazione finale.
Questa pagina descrive la strategia. Per il comportamento esatto di un singolo metodo, usare /integrations/tcpdf-compat/method-coverage/ insieme alla matrice autorevole nel repository docs/TCPDF_COVERAGE.md.
Modello di migrazione
Sezione intitolata “Modello di migrazione”Ogni fase mantiene l’applicazione distribuibile. Non serve mai un unico passaggio in blocco.
Fase 1 — Sostituire la dipendenza
Sezione intitolata “Fase 1 — Sostituire la dipendenza”Installare nextpdf/compat-legacy (vedere /integrations/tcpdf-compat/install/). Non rimuovere ancora tecnickcom/tcpdf — mantenere entrambi consente di eseguire confronti.
Scegliere come i punti di chiamata legacy risolvono la classe:
- Preferito: modificare
use/requireinuse NextPDF\Compat\Tcpdf\TCPDF;per ciascun file. È esplicito e facile da ricercare con grep. - Quando non si possono ancora toccare i punti di chiamata: abilitare una volta all’avvio gli alias globali opt-in con
LegacyBootstrap::enableAliases()(vedere /integrations/tcpdf-compat/boot-and-discovery/). In questo modo\TCPDFe le quattro classi di supporto vengono risolte sull’adattatore.
Le due strategie sono in pratica mutuamente esclusive. Se la libreria TCPDF reale è ancora caricabile automaticamente e si abilitano gli alias globali, l’alias viene saltato quando una classe
\TCPDFesiste già. Si rischia quindi di continuare a usare silenziosamente la TCPDF legacy. Durante la Fase 1, preferire gli import per singolo file, così da sapere esattamente quale classe usa ogni punto di chiamata. Vedere /integrations/tcpdf-compat/troubleshooting/.
Fase 2 — Eseguire la suite esistente senza modifiche
Sezione intitolata “Fase 2 — Eseguire la suite esistente senza modifiche”Eseguire l’intera suite di test sull’adattatore senza altre modifiche al codice. La maggior parte dei metodi delegati (94 dei circa 120 esaminati) si comporta in modo compatibile. Aspettarsi due classi di fallimenti prevedibili:
- Asserzioni a livello di byte. I test che confrontano i byte esatti del PDF falliranno perché il motore è un’implementazione indipendente. È un comportamento previsto, non un difetto. Rinviarli alla Fase 4.
- Diramazioni sul valore di ritorno. Alcuni metodi restituiscono segnaposto di compatibilità anziché valori calcolati — in particolare
MultiCell()restituisce1eWrite()restituisce0. Il codice che si dirama su tali valori di ritorno richiede un adeguamento.
Catalogare ogni fallimento. Classificare ciascuno come byte-baseline, return-value oppure divario comportamentale effettivo.
Fase 3 — Audit in modalità strict
Sezione intitolata “Fase 3 — Audit in modalità strict”Questa è la fase che rende sicura la migrazione. Eseguire la suite (o un percorso di produzione rappresentativo) con la modalità strict abilitata:
<?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 $e) { // Each message names the method, the ignored parameters, and a hint. fwrite(STDERR, 'MIGRATION GAP: ' . $e->getMessage() . "\n");}Ogni TcpdfNotImplementedException è un elemento di lavoro. Il messaggio contiene il metodo, l’elenco esatto dei parametri ignorati e un suggerimento di migrazione. L’insieme dei metodi che sollevano l’eccezione è elencato e verificato dai test in tests/Unit/Compat/Tcpdf/TcpdfStrictModeTest.php. La motivazione di ciascuno si trova in docs/TCPDF_COVERAGE.md.
Eseguire la modalità strict come job CI dedicato, non in produzione. Lo scopo è far emergere i divari, non generare eccezioni in produzione.
Fase 4 — Correggere i punti di chiamata
Sezione intitolata “Fase 4 — Correggere i punti di chiamata”Per ogni divario, scegliere la correzione corretta meno onerosa:
| Schema del divario | Correzione |
|---|---|
Il parametro ignorato non ha importanza (e.g. un $align di TCPDF su cui non si è mai fatto affidamento) | Eliminare il parametro. La chiamata diventa pienamente compatibile. |
Il parametro ignorato aveva importanza (e.g. un collegamento cliccabile su Image()) | Riesprimerlo tramite l’API moderna. Disegnare l’immagine, quindi aggiungere Document::link() sopra il rettangolo. |
Il metodo non è implementato (setSignature(), endPage()) | endPage() / Open(): rimuovere la chiamata. Firma: vedere /integrations/tcpdf-compat/security-and-operations/ — richiede un’edizione commerciale. |
Metodo non applicabile (setPDFVersion(), setUserRights()) | Rimuovere. L’output è sempre PDF 2.0; i diritti utente sono deprecati in PDF 2.0. |
| Diramazione sul valore di ritorno | Calcolare il valore autonomamente, oppure spostare quella logica nell’API moderna. |
Usare la via di fuga per tutto ciò che la superficie di TCPDF non può esprimere:
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\TCPDF;
$pdf = new TCPDF();$pdf->AddPage();
// Legacy path stays as-is for the parts that work:$pdf->SetFont('helvetica', '', 12);$pdf->Cell(0, 10, 'Header line', 0, 1);
// Modern path for what the TCPDF surface cannot express here:$document = $pdf->getDocument();$document->image('logo.png', 10, 30, 40, 0);$document->link(10, 30, 40, 20, 'https://example.com');Ricalibrare i test a livello di byte
Sezione intitolata “Ricalibrare i test a livello di byte”Sostituire le asserzioni sui byte esatti con asserzioni su ciò che conta davvero:
- L’output inizia con
%PDFe viene analizzato correttamente (livello smoke). - Il contenuto testuale renderizzato è presente (estrarre il testo ed eseguire lì le asserzioni).
- Le proprietà strutturali (numero di pagine, dimensione della pagina, presenza di una struttura) corrispondono.
È un costo una tantum e produce test capaci di sopravvivere ai futuri aggiornamenti del motore.
Fase 5 — Rimuovere la dipendenza da TCPDF
Sezione intitolata “Fase 5 — Rimuovere la dipendenza da TCPDF”Quando l’audit in modalità strict supera i controlli, con la modalità strict disattivata in produzione, e la suite è verde sulle asserzioni ricalibrate, rimuovere tecnickcom/tcpdf:
composer remove tecnickcom/tcpdfRieseguire la suite. Se qualcosa si risolve ancora nella classe TCPDF reale, vale l’avvertenza sugli alias della Fase 1 — correggere i punti di chiamata rimanenti affinché importino esplicitamente l’adattatore.
Fase 6 — Dismettere l’adattatore
Sezione intitolata “Fase 6 — Dismettere l’adattatore”L’adattatore è un ausilio alla migrazione, non un livello permanente. Una volta eliminato TCPDF e collaudato il motore, dismettere l’adattatore in modo incrementale:
- In ciascun modulo, sostituire
new TCPDF(...)con la costruzione modernaNextPDF\Core\Document. - Sostituire le chiamate ai metodi TCPDF con i loro equivalenti moderni (le chiamate
getDocument()già aggiunte nella Fase 4 sono il modello). - Quando un modulo non fa più riferimento all’adattatore, eliminarne gli import di compatibilità.
- Quando nessun modulo fa riferimento all’adattatore, rimuovere
nextpdf/compat-legacydacomposer.json.
A quel punto si usa l’API moderna PDF 2.0 senza alcun livello di compatibilità.
Checklist di migrazione
Sezione intitolata “Checklist di migrazione”-
nextpdf/compat-legacyinstallato; collegamento al motore verificato. - I punti di chiamata importano esplicitamente l’adattatore (oppure gli alias sono abilitati con la TCPDF reale rimossa dal percorso di autoload).
- Suite completa eseguita sull’adattatore; fallimenti classificati.
- Job CI in modalità strict aggiunto; ogni divario catalogato.
- Ogni divario corretto (eliminare il parametro / API moderna / rimuovere la chiamata).
- Asserzioni a livello di byte ricalibrate su content/structure.
-
tecnickcom/tcpdfrimosso; suite verde. - Adattatore dismesso modulo per modulo; dipendenza rimossa.
Vedere anche
Sezione intitolata “Vedere anche”- /integrations/tcpdf-compat/method-coverage/ — comportamento per metodo e indicazioni di sostituzione
docs/TCPDF_COVERAGE.md— matrice autorevole, verificata dai test- /integrations/tcpdf-compat/configuration/ — spostamento della configurazione dalle costanti globali
- /integrations/tcpdf-compat/security-and-operations/ — cifratura e firma durante la migrazione
- /integrations/tcpdf-compat/troubleshooting/ — il conflitto alias/real-TCPDF e altre insidie