Uruchamianie compat-legacy w produkcji
W skrócie
Dział zatytułowany „W skrócie”Adapter można bezpiecznie uruchamiać w handlerach protokołu Hypertext Transfer Protocol (HTTP), procesach roboczych kolejek i procesach długotrwałych. Jest bezpieczniejszy niż starsze TCPDF 6.2.13, ponieważ usuwa dwa zagrożenia produkcyjne, z którymi najłatwiej się zetknąć: bezpośredni zapis danych wyjściowych do bufora oraz die() przy błędzie. Ta strona pokazuje, jak używać go poprawnie.
Przed wdrożeniem produkcyjnym ukończ audyt trybu ścisłego opisany w /integrations/tcpdf-compat/migration/ i wdrażaj z trybem ścisłym wyłączonym.
Obsługa danych wyjściowych w procesach roboczych i procedurach obsługi
Dział zatytułowany „Obsługa danych wyjściowych w procesach roboczych i procedurach obsługi”Starsze Output() z TCPDF zapisuje dane bezpośrednio do aktywnego bufora wyjściowego. Może to uszkodzić odpowiedzi w środowiskach HTTP i zakłócić działanie procesów roboczych kolejek. Adapter zamiast tego kieruje dane wyjściowe przez bezpieczny mostek do miejsca docelowego.
Wybierz miejsce docelowe odpowiednie dla kodu wywołującego:
| Kontekst | Miejsce docelowe | Dlaczego |
|---|---|---|
| Proces roboczy kolejki zapisujący do magazynu | Output($path, 'F') | Zapisuje plik i zwraca pusty ciąg znaków. Nie wchodzi w interakcję z buforem. |
| Wygeneruj, a następnie attach/upload | Output($name, 'S') | Zwraca bajty formatu Portable Document Format (PDF); to ty decydujesz, gdzie trafią. |
| Załącznik wiadomości e-mail | Output($name, 'E') | Zwraca treść w formacie Multipurpose Internet Mail Extensions (MIME) zakodowaną w base64 z nagłówkiem Content-Type: application/pdf. |
| Odpowiedź HTTP, którą kontrolujesz | Output($name, 'S') | Pobiera bajty, a następnie samodzielnie ustawiasz nagłówki i treść. |
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\Exception\TcpdfNotImplementedException;use NextPDF\Compat\Tcpdf\TCPDF;
/** * Render an invoice in a queue worker. Returns the storage path. * * @throws \RuntimeException on a render failure (Error() throws, not die()). */function renderInvoiceJob(array $invoice, string $storageDir): string{ $pdf = new TCPDF('P', 'mm', 'A4'); $pdf->SetFont('helvetica', '', 12); $pdf->AddPage(); $pdf->Cell(0, 10, 'Invoice ' . $invoice['number'], 0, 1);
$path = $storageDir . '/invoice-' . $invoice['number'] . '.pdf';
try { $pdf->Output($path, 'F'); // writes file, no buffer pollution } catch (TcpdfNotImplementedException $e) { // Only reachable if strict mode is on — it must NOT be in production. throw new \RuntimeException('Adapter strict-mode gap in production: ' . $e->getMessage(), 0, $e); } catch (\RuntimeException $e) { // Error() throws RuntimeException instead of die(). throw new \RuntimeException('PDF render failed: ' . $e->getMessage(), 0, $e); }
return $path;}W handlerze HTTP preferuj 'S' i ustawiaj nagłówki samodzielnie:
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\TCPDF;
$pdf = new TCPDF();$pdf->AddPage();$pdf->SetFont('helvetica', '', 12);$pdf->Cell(0, 10, 'Report');
$bytes = $pdf->Output('report.pdf', 'S');
header('Content-Type: application/pdf');header('Content-Length: ' . strlen($bytes));header('Content-Disposition: inline; filename="report.pdf"');echo $bytes;Obsługa awarii
Dział zatytułowany „Obsługa awarii”Error() zgłasza RuntimeException; nigdy nie wywołuje die(). To najważniejsza zmiana operacyjna względem starszego TCPDF.
- Każdy punkt wejścia renderowania opakuj w
try/catch. - Odwzoruj wyjątek na kontrakt błędów aplikacji, taki jak HTTP 5xx, nieudane zadanie, ponowienie próby lub kolejka komunikatów nieobsłużonych.
- Nie zakładaj, że proces kończy się przy niepowodzeniu renderowania; tak się nie dzieje.
Wyjątek TcpdfNotImplementedException w okresowym zadaniu ciągłej integracji (CI) w trybie ścisłym (zalecane) oznacza rzeczywiste wykrycie problemu. Dana ścieżka kodu polega wtedy na nieobsługiwanym parametrze TCPDF. Potraktuj to jako zadanie migracyjne, a nie niestabilny test.
Cykl życia i obsługa zasobów
Dział zatytułowany „Cykl życia i obsługa zasobów”- Dokument buduje bajty PDF leniwie przy pierwszym wywołaniu danych wyjściowych.
Close()jest opcjonalne; jego wywołanie buforuje bajty.Open()to bezpieczna operacja pusta. endPage()nic nie robi, ponieważ NextPDF zarządza cyklem życia strony. Usuń je z gorących pętli; nie wnosi żadnej wartości.- Pozwól PHP zwalniać pamięć adaptera między zadaniami.
_destroy()resetuje buforowane dane adaptera, ale w typowych pętlach procesów roboczych nie trzeba wywoływać go jawnie. - Twórz nowy adapter dla każdego dokumentu. Nie używaj ponownie jednej instancji adaptera dla niepowiązanych dokumentów w procesie roboczym o długim czasie działania; stan dokumentu jest przypisany do instancji.
Wskazówki dotyczące wydajności
Dział zatytułowany „Wskazówki dotyczące wydajności”- Adapter to cienka warstwa delegująca; koszty są zdominowane przez silnik, a nie adapter.
- Zdefiniuj starsze stałe jednorazowo podczas uruchamiania.
LegacyDefaults::register()orazLegacyBootstrap::enableAliases()są idempotentne i zabezpieczone, więc powtarzane wywołania są tanie. Definiowanie stałych na każde żądanie marnuje pracę. - Preferuj
Output(..., 'S')lub'F'zamiast'I'/'D'w kontekstach innych niż przeglądarka. Ścieżki inline/download wytwarzają niezależne od środowiska dane wyjściowe, których zwykle nie chcesz w procesie roboczym. - W przypadku generowania o dużej skali profiluj silnik, a nie adapter. Budżet na stronę przeznaczony na własny narzut adaptera jest niewielki w porównaniu z renderowaniem.
Współbieżność
Dział zatytułowany „Współbieżność”- Każda instancja adaptera jest niezależna i przechowuje własny stan dokumentu. Współbieżność na poziomie procesu lub procesu roboczego jest bezpieczna, gdy każda jednostka pracy używa własnej instancji adaptera.
- Zabezpieczenia idempotentności w
LegacyBootstrapiLegacyDefaultskorzystają ze stanu statycznego lokalnego dla procesu; są bezpieczne w typowych modelach PHP per-request/per-worker. Nie są przeznaczone do współdzielenia zmiennego stanu między wątkami.
Lista kontrolna przed wdrożeniem produkcyjnym
Dział zatytułowany „Lista kontrolna przed wdrożeniem produkcyjnym”- Audyt trybu ścisłego ukończony; środowisko produkcyjne działa z wyłączonym trybem ścisłym.
- Wszystkie punkty wejścia renderowania opakowane w
try/catchdlaRuntimeException(bez polegania nadie()). - Procesy robocze używają
Output(..., 'F')lub'S', nigdy ścieżki inline. - Starsze stałe zdefiniowane jednorazowo podczas uruchamiania, przed pierwszą konstrukcją.
- Wdrożono okresowe zadanie CI w trybie ścisłym, które wykrywa regresje.
- Asercje testowe na poziomie bajtów mają zaktualizowaną linię bazową (zobacz /integrations/tcpdf-compat/migration/).
Zobacz też
Dział zatytułowany „Zobacz też”- /integrations/tcpdf-compat/security-and-operations/ — szyfrowanie, podejście do podpisywania i wzmacnianie zabezpieczeń
- /integrations/tcpdf-compat/troubleshooting/ — wzorce awarii produkcyjnych i sposoby ich rozwiązywania
- /integrations/tcpdf-compat/configuration/ — tryb ścisły i higiena stałych
- /integrations/tcpdf-compat/migration/ — audyt, który musi poprzedzać wdrożenie produkcyjne