Eine TCPDF-6.x-Codebasis auf NextPDF migrieren
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Das Paket nextpdf/compat-legacy stellt die öffentlichen Methodennamen, die Parameterreihenfolge und die Standardwerte von TCPDF 6.x über den Adapter NextPDF\Compat\Tcpdf\TCPDF auf Basis der NextPDF-Core-Engine bereit. Gehen Sie in dieser Reihenfolge vor: Wechseln Sie zuerst mit der kleinstmöglichen Änderung auf die Engine, weisen Sie nach, was bereits funktioniert, aktivieren Sie den Strict-Modus, um aufzulisten, was nicht funktioniert, korrigieren Sie die Aufrufstellen eine nach der anderen und ersetzen Sie den Adapter anschließend durch die moderne API. Der Adapter ist ein Migrationsgerüst, nicht das Ziel.
Voraussetzungen, gleich vorweg:
- NextPDF Core und
nextpdf/compat-legacysind installiert. - Sie haben eine bestehende TCPDF-6.x-Codebasis mit einer Test-Suite. Die Suite ist das Sicherheitsnetz für jede der folgenden Stufen.
Dies ist eine Schritt-für-Schritt-Anleitung. Für das Verhalten einzelner TCPDF-Aufrufe pro Methode lesen Sie die Seite zur Methodenabdeckung. Für die vollständige Datei-für-Datei-Strategie mit Code lesen Sie die übergeordnete Migrationsseite. Beide sind unter „Siehe auch“ verlinkt.
Installation
Abschnitt betitelt „Installation“Installieren Sie den Adapter zusätzlich zu Core. Entfernen Sie die echte TCPDF-Bibliothek noch nicht; wenn Sie beide behalten, können Sie die Ausgabe während der Migration vergleichen.
composer require nextpdf/compat-legacyBevor Sie Code ändern, vergewissern Sie sich, dass die Engine-Verknüpfung auflösbar ist (nextpdf/core ^3.0) und die Suite weiterhin läuft.
Konzeptioneller Überblick
Abschnitt betitelt „Konzeptioneller Überblick“Der Adapter ist eine Kompatibilitätsschicht, kein Fork von TCPDF und kein exakter Klon. Von rund 120 untersuchten öffentlichen TCPDF-6.x-Methoden werden etwa 94 direkt auf eine NextPDF\Core\Document-Operation abgebildet und verhalten sich für die dokumentierten Parameter kompatibel. Eine klar abgegrenzte Minderheit nimmt entweder Legacy-Parameter entgegen, die die Engine nicht berücksichtigt (stillschweigendes Ignorieren), oder erzeugt überhaupt keine Ausgabe (nicht implementiert oder nicht zutreffend). Die maßgebliche, testverifizierte Abdeckungsmatrix liegt im Paket-Repository unter docs/TCPDF_COVERAGE.md. Wenn dieser Leitfaden und diese Matrix sich widersprechen, ist die Matrix maßgeblich.
Zwei Tatsachen prägen die gesamte Migration:
- Die Ausgabebytes unterscheiden sich. Die Engine ist eine unabhängige PDF 2.0-Implementierung, daher unterscheiden sich die gerenderten Bytes von der TCPDF-Ausgabe, selbst wenn das sichtbare Ergebnis gleich aussieht. Tests, die exakte PDF-Bytes prüfen, müssen auf gerenderte Inhalte oder strukturelle Eigenschaften umgestellt werden.
- Der Strict-Modus ist Ihr Audit-Werkzeug. Bei ausgeschaltetem Strict-Modus (der Standard) fallen Methoden, die das TCPDF-Verhalten nicht reproduzieren können, stillschweigend auf ein eingeschränktes Verhalten zurück. Bei eingeschaltetem Strict-Modus werfen diese Aufrufe eine
TcpdfNotImplementedException, die genau die ignorierten Parameter und einen Migrationshinweis benennt. Führen Sie den Strict-Modus in einem eigenen Audit-Durchlauf aus, niemals in der Produktion.
Der Adapter stellt das gekapselte Engine-Dokument außerdem über getDocument() bereit, das das NextPDF\Core\Document zurückgibt. Das ist der Ausstiegspfad: Migrieren Sie die Aufrufstellen eine nach der anderen auf die moderne API, bis Sie den Adapter entfernen können.
API-Oberfläche
Abschnitt betitelt „API-Oberfläche“| Anliegen | Oberfläche |
|---|---|
| Erzeugen | new NextPDF\Compat\Tcpdf\TCPDF('P', 'mm', 'A4') |
| Optionale globale Aliase | NextPDF\Compat\Tcpdf\LegacyBootstrap::enableAliases() |
| Das Audit aktivieren | TCPDF::setStrictMode(true) |
| Audit-Exception | NextPDF\Compat\Tcpdf\Exception\TcpdfNotImplementedException |
| Notausstieg zur modernen API | TCPDF::getDocument(): NextPDF\Core\Document |
| Ausgabe | TCPDF::Output(string $name, string $dest) — S, F, E, I, D |
LegacyBootstrap::enableAliases() ist idempotent. Es registriert \TCPDF, \TCPDF_STATIC, \TCPDF_FONTS, \TCPDF_COLORS und \TCPDF_IMAGES nur dann, wenn diese Klassen noch nicht existieren. Die vollständige Abdeckung pro Methode und das Verhalten der Ausgabeziele finden Sie auf den Seiten zur Methodenabdeckung und zum Quickstart, die unter „Siehe auch“ verlinkt sind.
Code-Beispiel — Quickstart
Abschnitt betitelt „Code-Beispiel — Quickstart“Ändern Sie den Import, behalten Sie die Aufrufe im TCPDF-Stil bei und erzeugen Sie ein 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') schreibt die Datei und gibt einen leeren String zurück. Anders als beim Legacy-TCPDF gibt Output() des Adapters nichts in den aktiven Output-Buffer aus, daher können Sie es bedenkenlos in einem Queue-Worker oder einem HTTP-Handler aufrufen, der seine eigene Antwort steuert.
Wenn Sie Aufrufstellen, die new \TCPDF(...) im globalen Namespace verwenden, nicht ändern können, aktivieren Sie die optionalen Aliase einmalig beim Bootstrapping.
<?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');Aktivieren Sie keine Aliase, solange die echte TCPDF-Bibliothek noch autoloadbar ist. Der Alias wird übersprungen, wenn bereits eine \TCPDF-Klasse existiert, sodass Sie womöglich unbemerkt das Legacy-TCPDF weiterverwenden. Bevorzugen Sie während der Migration dateiweise Imports.
Code-Beispiel — Produktion
Abschnitt betitelt „Code-Beispiel — Produktion“Der migrationssichere Schritt ist das Strict-Modus-Audit. Führen Sie einen repräsentativen Produktionspfad oder die Suite mit eingeschaltetem Strict-Modus aus und sammeln Sie jede TcpdfNotImplementedException. Jede davon ist ein Arbeitspaket: Sie benennt die Methode, die ignorierten Parameter und einen Hinweis.
<?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");}Wählen Sie für jede Lücke die aufwandsärmste korrekte Lösung: Lassen Sie einen Parameter weg, auf den Sie sich nie verlassen haben, oder drücken Sie die Absicht über die moderne API via getDocument() neu aus. Der Notausstieg deckt alles ab, was die TCPDF-Oberfläche nicht ausdrücken kann.
<?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');Führen Sie den Strict-Modus als eigenen CI-Job aus, schalten Sie ihn anschließend ab und bringen Sie den auditierten Codepfad ins Deployment. Behalten Sie einen periodischen Strict-Modus-CI-Job bei, um Regressionen beim Refactoring abzufangen.
Randfälle & Fallstricke
Abschnitt betitelt „Randfälle & Fallstricke“MultiCell()gibt1zurück,Write()gibt0zurück. Das sind Kompatibilitätsplatzhalter, keine berechneten Werte. Passen Sie jeden Code an, der anhand dieser Rückgabewerte verzweigt.Error()wirft eine Exception, stattdie()aufzurufen. Der Adapter löst eineRuntimeExceptionaus. Code, der sich auf die Prozessbeendigung verlassen hat, muss die Exception abfangen.- Stillschweigend ignorierte Parameter. Methoden wie
Image(),writeHTML(),SetProtection()undBookmark()nehmen Legacy-Parameter entgegen, die ignoriert werden. Nutzen Sie den Strict-Modus, um sie zu finden. Für ein anklickbares Bild zeichnen Sie das Bild und fügen dannDocument::link()über demselben Rechteck hinzu. - Nicht implementierte Methoden.
setSignature(),addEmptySignatureAppearance()undendPage()sind No-Ops, die im Strict-Modus eine Exception werfen;Open()ist ein sicheres No-Op, das nie eine Exception wirft. Entfernen SieendPage()undOpen(). Für das Signieren ist eine kommerzielle NextPDF-Edition über die moderne Signatur-API erforderlich. - Die PDF-Version ist festgelegt.
setPDFVersion()kann nicht auf eine ältere PDF-Version umstellen; die Ausgabe ist immer PDF 2.0.setUserRights()ist in PDF 2.0 veraltet und wird mit einem Hinweis ignoriert. - Alias-Konflikt. Wenn nach dem Entfernen von
tecnickcom/tcpdfnoch irgendetwas auf die echte TCPDF-Klasse auflöst, hat die Alias-Schutzbedingung gegriffen; importieren Sie den Adapter an diesen Aufrufstellen explizit.
Performance
Abschnitt betitelt „Performance“Der Adapter delegiert an die Engine; der Aufwand für den Dokumentaufbau skaliert mit dem Inhalt, nicht mit der Adapterschicht. Da Output() des Adapters nicht in den Output-Buffer schreibt, ist es in einem Queue-Worker sicher. Verlagern Sie aufwendige Generierung im TCPDF-Stil vom Request-Thread weg, genauso wie Sie es bei jeder NextPDF-Generierung tun würden. Die Umstellung von Tests auf Byte-Ebene auf gerenderte Inhalte ist ein einmaliger Aufwand und liefert Tests, die künftige Engine-Upgrades überstehen.
Sicherheitshinweise
Abschnitt betitelt „Sicherheitshinweise“- Verschlüsselung.
SetProtection()ignoriert die Legacy-Parametermodeundpubkeys; die Engine verwendet AES-256 für den Standard-Handler. Für zertifikatsbasierte Verschlüsselung nutzen Sie den modernen Einstiegspunkt für Public-Key-Verschlüsselung, den der Adapter bereitstellt, nicht die Legacy-Parameter. - Signaturen sind editionsabhängig freigeschaltet. Die Unterstützung für Baseline-Signaturen ist eine Funktion der kommerziellen Edition, die über die moderne Signatur-API mit einem Zertifikats-Value-Object erreicht wird; das Legacy-
setSignature()ist ein No-Op. Dieser Leitfaden trifft für keine Edition Aussagen über Langzeitvalidierung oder zeitgestempelte Signaturprofile. - Lassen Sie das Audit explizit scheitern. Der Strict-Modus macht stillen Parameterverlust sichtbar, sodass ein Aufrufer erfährt, wenn seine Absicht nicht berücksichtigt wurde. Behandeln Sie die gesammelten Exceptions als Arbeitsliste für die Migration, nicht als Produktionsverhalten.
- Schreiben Sie niemals einen leeren
catch-Block. Das Audit-Beispiel fängtTcpdfNotImplementedExceptionab und schreibt eine definierte Arbeitspaket-Zeile.
Das vollständige Vorgehen zu Verschlüsselung und Signaturen während der Migration finden Sie auf der compat-legacy-Seite zu Sicherheit und Betrieb.
Konformität
Abschnitt betitelt „Konformität“Dieser Leitfaden erhebt selbst keinen normativen Standardanspruch. Der Adapter schreibt PDF 2.0-Ausgabe (ISO 32000-2) und kann nicht auf eine ältere Version zurückgehen. Dieses Verhalten und die zugehörige Klausel sind auf der vorgelagerten Seite zur Methodenabdeckung verankert, die auch das OWASP-Prinzip des expliziten Scheiterns hinter dem Strict-Modus und die Einordnung des Abdeckungs-Audits nach ISO/IEC 25023 zur funktionalen Vollständigkeit festhält. Diese Cookbook-Seite beschreibt die Verwendung und verweist für diese Zitate auf jene Seite.
Siehe auch
Abschnitt betitelt „Siehe auch“- Ein generiertes PDF aus einem Controller zurückgeben — Adapter-Ausgabe als HTTP-Antwort zurückgeben.
- compat-legacy Quickstart — erstes Dokument, Ausgabeziele und der Notausstieg.
- TCPDF-Methodenabdeckung — das Audit pro Methode und die maßgebliche Matrix.
- Von TCPDF 6.x zu NextPDF migrieren — die vollständige sechsstufige Strategie mit Code.