Migracja bazy kodu TCPDF 6.x na silnik NextPDF
W skrócie
Dział zatytułowany „W skrócie”Pakiet nextpdf/compat-legacy udostępnia publiczne nazwy metod, kolejność parametrów oraz wartości domyślne z TCPDF 6.x w adapterze NextPDF\Compat\Tcpdf\TCPDF, opartym na rdzeniu silnika NextPDF. Migruj w tej kolejności: przejdź na silnik przy możliwie najmniejszej zmianie, potwierdź, co już działa, włącz tryb ścisły, aby wykryć to, co nie działa, poprawiaj miejsca wywołań po kolei, a następnie wycofaj adapter i przejdź na nowoczesne API. Adapter ma wspierać migrację; nie jest jej celem.
Na początek wymagania wstępne:
- Rdzeń NextPDF oraz
nextpdf/compat-legacysą zainstalowane. - Masz istniejącą bazę kodu TCPDF 6.x i zestaw testów. Zestaw testów jest siatką bezpieczeństwa dla każdego z poniższych etapów.
To praktyczny przewodnik. Aby poznać zachowanie pojedynczego wywołania TCPDF w rozbiciu na metody, przeczytaj stronę pokrycia metod. Aby poznać pełną strategię plik po pliku wraz z kodem, przeczytaj nadrzędną stronę migracji. Oba odnośniki znajdują się w sekcji Zobacz też.
Instalacja
Dział zatytułowany „Instalacja”Zainstaluj adapter obok rdzenia. Nie usuwaj jeszcze oryginalnej biblioteki TCPDF — pozostawienie obu pozwala porównywać wynik w trakcie migracji.
composer require nextpdf/compat-legacyZanim zmienisz jakikolwiek kod, upewnij się, że zależność od silnika rozwiązuje się poprawnie (nextpdf/core ^3.0) i że zestaw testów nadal się uruchamia.
Przegląd koncepcyjny
Dział zatytułowany „Przegląd koncepcyjny”Adapter to warstwa zgodności, a nie odgałęzienie TCPDF ani klon identyczny bajt po bajcie. Spośród około 120 zbadanych publicznych metod TCPDF 6.x około 94 odwzorowuje się bezpośrednio na operację NextPDF\Core\Document i zachowuje się zgodnie dla udokumentowanych parametrów. Niewielka grupa pozostałych metod albo przyjmuje przestarzałe parametry, których silnik nie respektuje (ciche ignorowanie), albo nie daje żadnego wyniku (niezaimplementowane lub niemające zastosowania). Autorytatywna, zweryfikowana testami macierz pokrycia znajduje się w repozytorium pakietu pod adresem docs/TCPDF_COVERAGE.md. Gdy ten przewodnik i ta macierz są ze sobą sprzeczne, rozstrzyga macierz.
Dwa fakty kształtują całą migrację:
- Bajty wyniku się różnią. Silnik jest niezależną implementacją PDF 2.0, dlatego wyrenderowane bajty różnią się od wyniku TCPDF, nawet gdy widoczny rezultat wygląda tak samo. Testy, które weryfikują dokładne bajty PDF, wymagają ponownego wyznaczenia punktu odniesienia na podstawie wyrenderowanej zawartości lub właściwości strukturalnych.
- Tryb ścisły jest narzędziem audytu. Przy wyłączonym trybie ścisłym (ustawienie domyślne) metody, które nie potrafią odtworzyć zachowania TCPDF, degradują się po cichu. Przy włączonym trybie ścisłym te wywołania zgłaszają
TcpdfNotImplementedException, precyzyjnie wskazując zignorowane parametry oraz wskazówkę migracyjną. Uruchamiaj tryb ścisły w dedykowanym przebiegu audytowym, nigdy na produkcji.
Adapter udostępnia też bazowy dokument silnika przez getDocument(), który zwraca NextPDF\Core\Document. Wykorzystaj to jako ścieżkę wyjścia: migruj miejsca wywołań do nowoczesnego API po kolei, aż będzie można usunąć adapter.
Powierzchnia API
Dział zatytułowany „Powierzchnia API”| Zagadnienie | Powierzchnia |
|---|---|
| Konstruktor | new NextPDF\Compat\Tcpdf\TCPDF('P', 'mm', 'A4') |
| Opcjonalne aliasy globalne | NextPDF\Compat\Tcpdf\LegacyBootstrap::enableAliases() |
| Włączenie audytu | TCPDF::setStrictMode(true) |
| Wyjątek audytu | NextPDF\Compat\Tcpdf\Exception\TcpdfNotImplementedException |
| Furtka do nowoczesnego API | TCPDF::getDocument(): NextPDF\Core\Document |
| Wynik | TCPDF::Output(string $name, string $dest) — S, F, E, I, D |
Metoda LegacyBootstrap::enableAliases() jest idempotentna. Rejestruje \TCPDF, \TCPDF_STATIC, \TCPDF_FONTS, \TCPDF_COLORS oraz \TCPDF_IMAGES tylko wtedy, gdy te klasy jeszcze nie istnieją. Strony poświęcone pokryciu metod i szybkiemu startowi, do których odnośniki znajdują się w sekcji Zobacz też, opisują pełne zachowanie poszczególnych metod oraz miejsca docelowe wyniku.
Przykład kodu — szybki start
Dział zatytułowany „Przykład kodu — szybki start”Zmień import, zachowaj wywołania w stylu TCPDF i wygeneruj plik 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') zapisuje plik i zwraca pusty ciąg znaków. W przeciwieństwie do starszego TCPDF, Output() adaptera nie wypisuje danych do aktywnego bufora wyjścia, dzięki czemu możesz bezpiecznie wywołać tę metodę w procesie roboczym kolejki lub w procedurze obsługi żądania HTTP, która sama steruje swoją odpowiedzią.
Gdy nie możesz zmienić miejsc wywołań tworzących new \TCPDF(...) w przestrzeni globalnej, włącz opcjonalne aliasy jednorazowo podczas inicjalizacji.
<?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');Nie włączaj aliasów, dopóki oryginalna biblioteka TCPDF może być nadal ładowana automatycznie. Alias jest pomijany, gdy klasa \TCPDF już istnieje, więc możesz nadal używać starszego TCPDF, nie zdając sobie z tego sprawy. Podczas migracji preferuj importy w obrębie poszczególnych plików.
Przykład kodu — produkcja
Dział zatytułowany „Przykład kodu — produkcja”Bezpiecznym krokiem migracyjnym jest audyt w trybie ścisłym. Uruchom reprezentatywną ścieżkę produkcyjną lub zestaw testów z włączonym trybem ścisłym i zbierz każdy wyjątek TcpdfNotImplementedException. Każdy wyjątek to zadanie do wykonania: wskazuje metodę, zignorowane parametry oraz wskazówkę.
<?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");}Dla każdej rozbieżności wybierz najmniej kosztowną poprawną korektę: usuń parametr, na którym nigdy nie polegałeś, albo wyraź intencję w nowoczesnym API za pomocą getDocument(). Furtka obsługuje wszystko, czego powierzchnia TCPDF nie potrafi wyrazić.
<?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');Uruchamiaj tryb ścisły jako dedykowane zadanie ciągłej integracji (CI), a następnie wyłącz go i wdróż zaudytowaną ścieżkę kodu. Utrzymuj okresowe zadanie CI w trybie ścisłym, aby wyłapywać regresje podczas refaktoryzacji.
Przypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”MultiCell()zwraca1, aWrite()zwraca0. Są to wartości zastępcze zapewniające zgodność, a nie wartości obliczane. Dostosuj każdy fragment kodu, który rozgałęzia się w zależności od tych wartości zwracanych.Error()zgłasza wyjątek zamiast wywoływaćdie(). Adapter zgłaszaRuntimeException. Kod, który polega na zakończeniu procesu, musi przechwytywać ten wyjątek.- Po cichu ignorowane parametry. Metody takie jak
Image(),writeHTML(),SetProtection()orazBookmark()przyjmują przestarzałe parametry, które są ignorowane. Użyj trybu ścisłego, aby je znaleźć. Aby uzyskać klikalny obraz, narysuj obraz, a następnie dodajDocument::link()na tym samym prostokącie. - Niezaimplementowane metody.
setSignature(),addEmptySignatureAppearance()orazendPage()to operacje puste, które w trybie ścisłym zgłaszają wyjątek;Open()jest bezpieczną operacją pustą, która nigdy nie zgłasza wyjątku. UsuńendPage()orazOpen(). Podpisywanie wymaga komercyjnej edycji NextPDF i nowoczesnego API podpisu. - Wersja PDF jest stała.
setPDFVersion()nie potrafi obniżyć wyniku do starszej wersji PDF; wynikiem jest zawsze PDF 2.0.setUserRights()jest wycofana w PDF 2.0 i jest ignorowana z powiadomieniem. - Konflikt aliasów. Jeśli cokolwiek nadal rozwiązuje się do prawdziwej klasy TCPDF po usunięciu
tecnickcom/tcpdf, ma zastosowanie zastrzeżenie dotyczące aliasów — zaimportuj adapter jawnie w tych miejscach wywołań.
Wydajność
Dział zatytułowany „Wydajność”Adapter deleguje zadania do silnika; koszt budowania dokumentu skaluje się wraz z zawartością, a nie z warstwą adaptera. Ponieważ Output() adaptera nie zapisuje danych do bufora wyjścia, jest bezpieczne w procesie roboczym kolejki — przenieś ciężkie generowanie w stylu TCPDF poza wątek żądania w taki sam sposób, w jaki przeniósłbyś dowolne generowanie NextPDF. Ponowne wyznaczenie punktu odniesienia dla testów na poziomie bajtów na podstawie wyrenderowanej zawartości to koszt jednorazowy, a w zamian otrzymujesz testy, które przetrwają przyszłe aktualizacje silnika.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”- Szyfrowanie.
SetProtection()ignoruje przestarzałe parametrymodeipubkeys; silnik używa AES-256 w standardowym handlerze. W przypadku szyfrowania opartego na certyfikatach użyj nowoczesnego punktu wejścia szyfrowania kluczem publicznym udostępnionego w adapterze, a nie przestarzałych parametrów. - Podpisywanie jest ograniczone. Obsługa podpisu Baseline to funkcja edycji komercyjnej dostępna przez nowoczesne API podpisu z obiektem wartości certyfikatu; przestarzała metoda
setSignature()jest operacją pustą. Ten przewodnik nie formułuje żadnych twierdzeń dotyczących walidacji długoterminowej ani profili podpisu ze znacznikiem czasu dla jakiejkolwiek edycji. - Sygnalizuj błędy jawnie podczas audytu. Tryb ścisły uwidacznia ciche pomijanie parametrów, dzięki czemu wiesz, kiedy adapter nie uszanował intencji wywołującego. Traktuj zebrane wyjątki jako listę zadań migracyjnych, a nie jako zachowanie produkcyjne.
- Nigdy nie pisz pustego bloku
catch. Przykład audytu przechwytujeTcpdfNotImplementedExceptioni zapisuje zdefiniowany wiersz z zadaniem do wykonania.
Pełne stanowisko dotyczące szyfrowania i podpisu podczas migracji opisano na stronie compat-legacy poświęconej bezpieczeństwu i operacjom.
Zgodność
Dział zatytułowany „Zgodność”Ten przewodnik nie formułuje własnych twierdzeń o zgodności ze standardami normatywnymi. Adapter zapisuje wynik w formacie PDF 2.0 (ISO 32000-2) i nie potrafi obniżyć go do starszej wersji. To zachowanie i odpowiednia klauzula są przypięte na nadrzędnej stronie pokrycia metod, która rejestruje również zasadę jawnej sygnalizacji błędów OWASP stojącą za trybem ścisłym oraz ujęcie audytu pokrycia w kategoriach kompletności funkcjonalnej według ISO/IEC 25023. Ta strona poradnika powtarza sposób użycia i odsyła po te cytowania do strony nadrzędnej.
Zobacz też
Dział zatytułowany „Zobacz też”- Zwracanie wygenerowanego pliku PDF z kontrolera — zwracanie wyniku adaptera jako odpowiedzi HTTP.
- Szybki start compat-legacy — pierwszy dokument, miejsca docelowe wyniku oraz furtka.
- Pokrycie metod TCPDF — audyt poszczególnych metod oraz autorytatywna macierz.
- Migracja z TCPDF 6.x do NextPDF — pełna sześcioetapowa strategia z kodem.