Ga naar inhoud

Een TCPDF 6.x-codebase migreren naar NextPDF

Het pakket nextpdf/compat-legacy biedt de publieke methodenamen, parametervolgorde en standaardwaarden van TCPDF 6.x aan boven op de NextPDF core-engine via de NextPDF\Compat\Tcpdf\TCPDF-adapter. Pak de migratie in deze volgorde aan: stap met de kleinst mogelijke wijziging over naar de engine, bewijs wat al werkt, schakel de strikte modus in om te vinden wat niet werkt, herstel de aanroepplaatsen één voor één en bouw daarna de adapter af om de moderne API te gebruiken. De adapter ondersteunt de migratie; hij is niet de eindbestemming.

Vereisten vooraf:

  • NextPDF core en nextpdf/compat-legacy zijn geïnstalleerd.
  • Je beschikt over een bestaande TCPDF 6.x-codebase met een testsuite. De suite is het vangnet voor elke fase hieronder.

Dit is een handleiding. Raadpleeg voor het gedrag per methode van een afzonderlijke TCPDF-aanroep de pagina over methodedekking. Raadpleeg voor de volledige bestand-voor-bestandstrategie met code de upstream migratiepagina. Beide links staan onder Zie ook.

Installeer de adapter naast core. Verwijder de echte TCPDF-bibliotheek nog niet; als je beide behoudt, kun je de uitvoer vergelijken terwijl je migreert.

Terminal window
composer require nextpdf/compat-legacy

Controleer voordat je code wijzigt of de engine-koppeling oplost (nextpdf/core ^3.0) en of de suite nog steeds draait.

De adapter is een compatibiliteitslaag, geen fork van TCPDF en geen byte-identieke kloon. Van de ongeveer 120 onderzochte publieke methoden van TCPDF 6.x komen er ongeveer 94 rechtstreeks overeen met een bewerking van NextPDF\Core\Document en gedragen ze zich compatibel voor de gedocumenteerde parameters. Een duidelijk afgebakende minderheid accepteert verouderde parameters die de engine niet honoreert (en dus stilzwijgend negeert), of produceert geen uitvoer (niet geïmplementeerd of niet van toepassing). De gezaghebbende, met tests geverifieerde dekkingsmatrix staat in de pakketrepository op docs/TCPDF_COVERAGE.md. Als deze handleiding en die matrix elkaar tegenspreken, geldt de matrix.

Twee feiten bepalen de hele migratie:

  • De uitvoerbytes verschillen. De engine is een onafhankelijke PDF 2.0-implementatie, dus de uitvoerbytes verschillen van de uitvoer van TCPDF, zelfs wanneer het zichtbare resultaat hetzelfde lijkt. Tests die op exacte PDF-bytes controleren, moeten opnieuw worden geijkt op weergegeven inhoud of structurele eigenschappen.
  • De strikte modus is je auditinstrument. Met de strikte modus uit (de standaard) vallen methoden die TCPDF-gedrag niet kunnen reproduceren stilzwijgend terug. Met de strikte modus aan werpen die aanroepen TcpdfNotImplementedException, met de exact genegeerde parameters en een migratiehint. Draai de strikte modus in een aparte auditronde, nooit in productie.

De adapter stelt ook het onderliggende engine-document beschikbaar via getDocument(), dat het NextPDF\Core\Document teruggeeft. Gebruik dat als uitstapweg: migreer de aanroepplaatsen één voor één naar de moderne API totdat je de adapter kunt verwijderen.

AandachtspuntOppervlak
Construerennew NextPDF\Compat\Tcpdf\TCPDF('P', 'mm', 'A4')
Globale aliassen via opt-inNextPDF\Compat\Tcpdf\LegacyBootstrap::enableAliases()
De audit inschakelenTCPDF::setStrictMode(true)
Audit-uitzonderingNextPDF\Compat\Tcpdf\Exception\TcpdfNotImplementedException
Uitstapweg naar de moderne APITCPDF::getDocument(): NextPDF\Core\Document
UitvoerTCPDF::Output(string $name, string $dest)S, F, E, I, D

LegacyBootstrap::enableAliases() is idempotent. Het registreert \TCPDF, \TCPDF_STATIC, \TCPDF_FONTS, \TCPDF_COLORS en \TCPDF_IMAGES alleen wanneer die klassen nog niet bestaan. De pagina’s over methodedekking en de snelstart waarnaar onder Zie ook wordt verwezen, behandelen het volledige gedrag per methode en de uitvoerbestemmingen.

Pas de import aan, behoud de aanroepen in TCPDF-stijl en produceer een PDF.

quickstart-first.php
<?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') schrijft het bestand en geeft een lege tekenreeks terug. Anders dan de verouderde TCPDF-implementatie schrijft de Output() van de adapter niets naar de actieve uitvoerbuffer, zodat je hem veilig kunt aanroepen binnen een wachtrijworker of een HTTP-handler die zijn eigen respons beheert.

Wanneer je aanroepplaatsen die new \TCPDF(...) in de globale naamruimte construeren niet kunt wijzigen, schakel dan de opt-in-aliassen eenmalig bij het opstarten in.

quickstart-alias.php
<?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');

Schakel geen aliassen in zolang de echte TCPDF-bibliotheek nog automatisch laadbaar is. De alias wordt overgeslagen wanneer er al een \TCPDF-klasse bestaat, waardoor je zonder het te beseffen het verouderde TCPDF kunt blijven gebruiken. Geef tijdens de migratie de voorkeur aan imports per bestand.

De migratieveilige stap is de audit met de strikte modus. Draai een representatief productiepad, of de suite, met de strikte modus aan en verzamel elke TcpdfNotImplementedException. Elke uitzondering is een werkitem: ze benoemt de methode, de genegeerde parameters en een hint.

migration-audit.php
<?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");
}

Kies voor elk verschil de goedkoopste juiste oplossing: laat een parameter vallen waarop je nooit hebt vertrouwd, of breng de bedoeling tot uitdrukking via de moderne API met getDocument(). De uitstapweg verwerkt alles wat het TCPDF-oppervlak niet kan uitdrukken.

migration-escape-hatch.php
<?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');

Laat de strikte modus draaien als een aparte continuous-integration-taak (CI), schakel hem daarna uit en implementeer het geauditeerde codepad. Houd een periodieke CI-taak in de strikte modus aan om regressies op te sporen terwijl je refactort.

  • MultiCell() geeft 1 terug, Write() geeft 0 terug. Dit zijn compatibiliteitsplaceholders, geen berekende waarden. Pas code aan die op die retourwaarden vertakt.
  • Error() werpt een uitzondering in plaats van die() aan te roepen. De adapter werpt RuntimeException. Code die op procesbeëindiging vertrouwt, moet de uitzondering opvangen.
  • Stilzwijgend genegeerde parameters. Methoden zoals Image(), writeHTML(), SetProtection() en Bookmark() accepteren verouderde parameters die worden genegeerd. Gebruik de strikte modus om ze te vinden. Teken voor een klikbare afbeelding eerst de afbeelding en voeg daarna Document::link() over dezelfde rechthoek toe.
  • Niet-geïmplementeerde methoden. setSignature(), addEmptySignatureAppearance() en endPage() zijn no-ops die in de strikte modus een uitzondering werpen; Open() is een veilige no-op die nooit een uitzondering werpt. Verwijder endPage() en Open(). Ondertekening vereist een commerciële NextPDF-editie via de moderne handtekening-API.
  • De PDF-versie ligt vast. setPDFVersion() kan niet terugschakelen naar een oudere PDF-versie; de uitvoer is altijd PDF 2.0. setUserRights() is verouderd in PDF 2.0 en wordt genegeerd met een melding.
  • Aliasconflict. Als er na het verwijderen van tecnickcom/tcpdf nog iets naar de echte TCPDF-klasse oplost, blijft het aliasvoorbehoud gelden — importeer de adapter expliciet op die aanroepplaatsen.

De adapter delegeert naar de engine; de kosten van het opbouwen van een document schalen met de inhoud, niet met de adapterlaag. Omdat de Output() van de adapter niet naar de uitvoerbuffer schrijft, is hij veilig binnen een wachtrijworker — verplaats zware generatie in TCPDF-stijl van de aanvraagthread op dezelfde manier als je elke NextPDF-generatie zou verplaatsen. Het opnieuw ijken van tests op byte-niveau op weergegeven inhoud is een eenmalige kostenpost en levert je tests op die toekomstige engine-upgrades overleven.

  • Versleuteling. SetProtection() negeert de verouderde parameters mode en pubkeys; de engine gebruikt AES-256 voor de standaardhandler. Gebruik voor certificaatgebaseerde versleuteling het moderne ingangspunt voor publiekesleutelversleuteling dat op de adapter beschikbaar is, niet de verouderde parameters.
  • Ondertekening is afgeschermd. Baseline-ondersteuning voor handtekeningen is een mogelijkheid van de commerciële editie die je bereikt via de moderne handtekening-API met een certificaat-waardeobject; de verouderde setSignature() is een no-op. Deze handleiding doet voor geen enkele editie uitspraken over langetermijnvalidatie of handtekeningprofielen met tijdstempel.
  • Faal expliciet tijdens de audit. De strikte modus maakt stilzwijgend parameterverlies zichtbaar, zodat u weet wanneer de adapter de bedoeling van de aanroeper niet heeft gehonoreerd. Beschouw de verzamelde uitzonderingen als de migratiewerklijst, niet als productiegedrag.
  • Schrijf nooit een leeg catch-blok. Het auditvoorbeeld vangt TcpdfNotImplementedException op en schrijft een gedefinieerde werkitemregel weg.

De volledige aanpak voor versleuteling en handtekeningen tijdens de migratie staat op de pagina over beveiliging en beheer van compat-legacy.

Deze handleiding doet zelf geen normatieve standaardenclaim. De adapter schrijft uitvoer in PDF 2.0 (ISO 32000-2) en kan niet terugschakelen naar een oudere versie. Dat gedrag en de bijbehorende clausule staan vastgelegd op de upstream pagina over methodedekking, die ook het OWASP-principe van expliciet falen achter de strikte modus en de ISO/IEC 25023-kadering van functionele volledigheid van de dekkingsaudit vastlegt. Deze cookbook-pagina herhaalt het gebruik en laat die verwijzingen aan de upstream pagina over.