Migration von TCPDF 6.x zu NextPDF
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Die Migration folgt einer klaren Reihenfolge. Stellen Sie zunächst mit der kleinstmöglichen Änderung auf die NextPDF-Engine um. Weisen Sie nach, was bereits funktioniert. Prüfen Sie, was noch nicht funktioniert. Beheben Sie die Probleme Aufrufstelle für Aufrufstelle. Entfernen Sie anschließend den Adapter. Die Kompatibilitätsschicht unterstützt die Schritte zwei bis vier; sie ist nicht das Ziel.
Diese Seite beschreibt die Strategie. Das genaue Verhalten einzelner Methoden finden Sie unter /integrations/tcpdf-compat/method-coverage/ und in der maßgeblichen Matrix im Repository docs/TCPDF_COVERAGE.md.
Migrationsmodell
Abschnitt betitelt „Migrationsmodell“In jeder Stufe bleibt die Anwendung auslieferbar. Eine vollständige Umstellung auf einen Schlag ist nie erforderlich.
Stufe 1 — Die Abhängigkeit austauschen
Abschnitt betitelt „Stufe 1 — Die Abhängigkeit austauschen“Installieren Sie nextpdf/compat-legacy (siehe /integrations/tcpdf-compat/install/). Entfernen Sie tecnickcom/tcpdf noch nicht — wenn Sie beide behalten, können Sie einen Vergleich durchführen.
Wählen Sie, wie Legacy-Aufrufstellen die Klasse auflösen sollen:
- Bevorzugt: Ändern Sie
use/requirepro Datei zuuse NextPDF\Compat\Tcpdf\TCPDF;. So bleibt es explizit und per grep auffindbar. - Wenn Sie die Aufrufstellen noch nicht anfassen können: Aktivieren Sie die optionalen globalen Aliase einmalig beim Bootvorgang mit
LegacyBootstrap::enableAliases()(siehe /integrations/tcpdf-compat/boot-and-discovery/). Dadurch werden\TCPDFund die vier Hilfsklassen auf den Adapter aufgelöst.
Die beiden Strategien schließen sich in der Praxis gegenseitig aus. Wenn die echte TCPDF-Bibliothek weiterhin über den Autoload ladbar ist und Sie globale Aliase aktivieren, wird der Alias übersprungen, wenn bereits eine
\TCPDF-Klasse existiert. Möglicherweise verwenden Sie dann stillschweigend weiterhin das Legacy-TCPDF. Bevorzugen Sie in Stufe 1 Importe pro Datei, damit Sie genau wissen, welche Klasse jede Aufrufstelle verwendet. Siehe /integrations/tcpdf-compat/troubleshooting/.
Stufe 2 — Die vorhandene Suite unverändert ausführen
Abschnitt betitelt „Stufe 2 — Die vorhandene Suite unverändert ausführen“Führen Sie Ihre vollständige Test-Suite gegen den Adapter aus, ohne weitere Codeänderungen vorzunehmen. Die meisten delegierten Methoden (94 der ~120 untersuchten) verhalten sich kompatibel. Rechnen Sie mit zwei vorhersehbaren Fehlerarten:
- Assertions auf Byte-Ebene. Tests, die exakte PDF-Bytes vergleichen, schlagen fehl, weil die Engine eine eigenständige Implementierung ist. Das ist erwartet, kein Fehler. Behandeln Sie diese erst in Stufe 4.
- Verzweigungen anhand von Rückgabewerten. Einige Methoden geben Kompatibilitätsplatzhalter anstelle berechneter Werte zurück — insbesondere
MultiCell()gibt1zurück undWrite()gibt0zurück. Code, der anhand dieser Rückgabewerte verzweigt, muss angepasst werden.
Katalogisieren Sie jeden Fehler. Klassifizieren Sie ihn als Byte-Baseline, Rückgabewert oder echte Verhaltenslücke.
Stufe 3 — Audit im Strict-Modus
Abschnitt betitelt „Stufe 3 — Audit im Strict-Modus“Diese Stufe macht die Migration sicher. Führen Sie die Suite (oder einen repräsentativen Produktionspfad) mit aktiviertem Strict-Modus aus:
<?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");}Jede TcpdfNotImplementedException ist ein Arbeitspaket. Die Meldung enthält die Methode, die genaue Liste der ignorierten Parameter und einen Migrationshinweis. Die Methoden, die eine Ausnahme werfen, sind in tests/Unit/Compat/Tcpdf/TcpdfStrictModeTest.php aufgezählt und per Test abgesichert. Die Begründung dafür findet sich jeweils in docs/TCPDF_COVERAGE.md.
Führen Sie den Strict-Modus als dedizierten CI-Job aus, nicht in der Produktion. Ziel ist, die Lücken sichtbar zu machen, nicht in der Produktion Ausnahmen auszulösen.
Stufe 4 — Aufrufstellen beheben
Abschnitt betitelt „Stufe 4 — Aufrufstellen beheben“Wählen Sie für jede Lücke die kostengünstigste korrekte Lösung:
| Lückenmuster | Lösung |
|---|---|
Ignorierter Parameter ist unerheblich (z. B. ein TCPDF-$align, auf den Sie sich nie verlassen haben) | Entfernen Sie den Parameter. Der Aufruf ist dann exakt kompatibel. |
Ignorierter Parameter war relevant (z. B. ein anklickbarer Image()-Link) | Bilden Sie ihn über die moderne API ab. Zeichnen Sie das Bild und fügen Sie dann Document::link() über dem Rechteck hinzu. |
Methode ist nicht implementiert (setSignature(), endPage()) | endPage() / Open(): Entfernen Sie den Aufruf. Signieren: siehe /integrations/tcpdf-compat/security-and-operations/ — erfordert eine kommerzielle Edition. |
Nicht zutreffende Methode (setPDFVersion(), setUserRights()) | Entfernen. Die Ausgabe ist immer PDF 2.0; user-rights sind in PDF 2.0 veraltet. |
| Verzweigung anhand eines Rückgabewerts | Berechnen Sie den Wert selbst oder verlagern Sie diese Logik in die moderne API. |
Verwenden Sie die Ausweichlösung für alles, was sich über die TCPDF-Oberfläche nicht ausdrücken lässt:
<?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');Byte-Level-Tests als neue Baseline festlegen
Abschnitt betitelt „Byte-Level-Tests als neue Baseline festlegen“Ersetzen Sie Assertions auf exakte Bytes durch Assertions auf das, was tatsächlich zählt:
- Die Ausgabe beginnt mit
%PDFund lässt sich parsen (Smoke-Level). - Der gerenderte Textinhalt ist vorhanden (extrahieren Sie den Text und prüfen Sie ihn mit einer Assertion).
- Strukturelle Eigenschaften (Seitenzahl, Seitengröße, Vorhandensein einer Gliederung) stimmen überein.
Dieser einmalige Aufwand liefert Tests, die künftige Engine-Upgrades überstehen.
Stufe 5 — Die TCPDF-Abhängigkeit entfernen
Abschnitt betitelt „Stufe 5 — Die TCPDF-Abhängigkeit entfernen“Sobald das Audit im Strict-Modus erfolgreich ist, der Strict-Modus in der Produktion aus ist und die Suite mit den neu als Baseline festgelegten Assertions grün ist, entfernen Sie tecnickcom/tcpdf:
composer remove tecnickcom/tcpdfFühren Sie die Suite erneut aus. Wenn noch etwas auf die echte TCPDF-Klasse aufgelöst wird, hat sich der Alias-Vorbehalt aus Stufe 1 bestätigt — passen Sie die verbleibenden Aufrufstellen so an, dass sie den Adapter explizit importieren.
Stufe 6 — Den Adapter außer Betrieb nehmen
Abschnitt betitelt „Stufe 6 — Den Adapter außer Betrieb nehmen“Der Adapter ist eine Migrationshilfe, keine dauerhafte Schicht. Nachdem TCPDF entfernt und die Engine erprobt ist, nehmen Sie den Adapter schrittweise außer Betrieb:
- Ersetzen Sie in jedem Modul
new TCPDF(...)durch die moderne Konstruktion mitNextPDF\Core\Document. - Ersetzen Sie TCPDF-Methodenaufrufe durch ihre modernen Entsprechungen (die
getDocument()-Aufrufe, die Sie bereits in Stufe 4 hinzugefügt haben, dienen als Vorlage). - Wenn ein Modul den Adapter nicht mehr referenziert, löschen Sie seine Kompatibilitätsimporte.
- Wenn kein Modul den Adapter referenziert, entfernen Sie
nextpdf/compat-legacyauscomposer.json.
Sie verwenden dann die moderne PDF-2.0-API ohne Kompatibilitätsschicht.
Migrations-Checkliste
Abschnitt betitelt „Migrations-Checkliste“-
nextpdf/compat-legacyinstalliert; Engine-Anbindung verifiziert. - Aufrufstellen importieren den Adapter explizit (oder Aliase sind aktiviert, wobei das echte TCPDF aus dem Autoload-Pfad entfernt ist).
- Vollständige Suite gegen den Adapter ausgeführt; Fehler klassifiziert.
- CI-Job für den Strict-Modus hinzugefügt; jede Lücke katalogisiert.
- Jede Lücke behoben (Parameter entfernt / moderne API genutzt / Aufruf entfernt).
- Byte-Level-Assertions auf content/structure als neue Baseline festgelegt.
-
tecnickcom/tcpdfentfernt; Suite grün. - Adapter Modul für Modul außer Betrieb genommen; Abhängigkeit entfernt.
Siehe auch
Abschnitt betitelt „Siehe auch“- /integrations/tcpdf-compat/method-coverage/ — Verhalten pro Methode und Hinweise zum Ersatz
docs/TCPDF_COVERAGE.md— maßgebliche, per Test verifizierte Matrix- /integrations/tcpdf-compat/configuration/ — globale Konstanten über die Konfiguration auflösen
- /integrations/tcpdf-compat/security-and-operations/ — Verschlüsselung und Signieren während der Migration
- /integrations/tcpdf-compat/troubleshooting/ — der alias/real-TCPDF-Konflikt und weitere Fallstricke