Przejdź do głównej zawartości

Przewodnik dewelopera po Laravelu

Pakiet dla Laravela dopasowuje NextPDF do konwencji Laravela, nie zmieniając podstawowego cyklu życia dokumentu. Kontener odpowiada za współdzielone rejestry i fabryki. Każdy dokument PDF jest jednorazowy, dlatego należy go zbudować, zwrócić, przesłać strumieniowo albo zapisać tylko raz.

Skorzystaj z tego przewodnika podczas projektowania usług aplikacyjnych, zadań kolejkowych, przepływów odpowiedzi lub pokrycia testami dla nextpdf/laravel.

WarstwaWłaścicielOdpowiedzialnośćCzego tu nie umieszczać
KontrolerAplikacjaAutoryzuje żądanie, wybiera konstruktor dokumentu i zwraca odpowiedź.Reguły układu PDF współdzielone między przypadkami użycia.
Usługa aplikacyjnaAplikacjaZbiera dane domenowe i wywołuje kod budujący dokument.Logika startowa kontenera lub konfiguracja pakietu.
Konstruktor dokumentuAplikacjaPrzekłada dane domenowe na wywołania dokumentu NextPDF.Obiekty żądań, logika zapytań Eloquent lub szczegóły transportu kolejki.
Integracja z Laravelemnextpdf/laravelWiąże fabryki, rejestry, podpisującego, klienta TSA, fasadę, odpowiedzi oraz zadanie kolejkowe.Ścieżki przechowywania specyficzne dla biznesu lub polityka najemcy.
Silnik podstawowynextpdf/nextpdfBuduje i serializuje plik PDF.Polityka odpowiedzi, kolejki lub systemu plików Laravela.
EtapZachowanieDziałanie dewelopera
Rejestracja dostawcy usługNextPdfServiceProvider::register() rejestruje współdzielone rejestry, fabrykę dokumentów, powiązanie dokumentu, klienta HTTP, klienta urzędu znacznika czasu (TSA), podpisującego oraz opcjonalne kontrakty e-faktur.Przed wdrożeniem produkcyjnym opublikuj i przejrzyj plik config/nextpdf.php.
Rozwiązanie dokumentuFasada Pdf oraz powiązanie PdfDocumentInterface rozwiązują świeży dokument za pośrednictwem DocumentFactoryInterface.Rozwiązuj dokument raz na żądanie, polecenie lub zadanie w kolejce.
Tworzenie zawartościKod aplikacji wywołuje bazowe API dokumentu przez fasadę lub wstrzyknięty dokument.Trzymaj pobieranie danych domenowych poza konstruktorem dokumentu.
Wyjście końcowePdfResponse emituje wyjście HTTP albo dokument jest zapisywany na dysku.Dla każdego dokumentu wybierz jedną końcową ścieżkę wyjścia.
Wykonanie w kolejceGeneratePdfJob odbudowuje dokument w procesie roboczym i ponownie weryfikuje ścieżkę wyjścia.Przekazuj kontekst skalarny i utrzymuj idempotentność wywołań zwrotnych.
ŚcieżkaPrzeznaczenie
app/Pdf/Builders/*Czyste konstruktory dokumentów. Przyjmują dane i zwracają gotowy dokument.
app/Pdf/Data/*Małe obiekty transferu danych (DTO) przenoszące już autoryzowane dane wejściowe dokumentu.
app/Services/*Orkiestracja logiki aplikacyjnej, zapytania, obsługa autoryzacji oraz wybór ścieżki przechowywania.
app/Jobs/*Opcjonalne opakowania wokół GeneratePdfJob, gdy aplikacja potrzebuje nazwanych zadań.
tests/Feature/Pdf/*Testy odpowiedzi HTTP, wysyłki do kolejki oraz autoryzacji.
tests/Unit/Pdf/*Testy konstruktorów z małymi, deterministycznymi danymi wejściowymi.

Utrzymuj konstruktory niezależne od obiektów żądań Laravela. Konstruktor powinno dać się wywołać z kontrolera, polecenia, testu lub procesu roboczego kolejki z tymi samymi danymi wejściowymi.

<?php
namespace App\Pdf\Builders;
use App\Pdf\Data\InvoicePdfData;
use NextPDF\Contracts\PdfDocumentInterface;
final readonly class InvoicePdfBuilder
{
public function build(PdfDocumentInterface $pdf, InvoicePdfData $data): PdfDocumentInterface
{
$pdf->setTitle($data->title)
->addPage()
->setFont('dejavusans', '', 12)
->writeHtml($data->html);
return $pdf;
}
}

Stosuj wstrzykiwanie przez konstruktor, gdy przepływ PDF jest częścią logiki aplikacji. Fasady używaj wyłącznie w krótkich przepływach kontrolera, gdzie styl statyczny jest łatwiejszy do odczytania.

<?php
namespace App\Http\Controllers;
use App\Pdf\Builders\InvoicePdfBuilder;
use App\Pdf\Data\InvoicePdfData;
use NextPDF\Contracts\PdfDocumentInterface;
use NextPDF\Laravel\Http\PdfResponse;
final readonly class DownloadInvoiceController
{
public function __invoke(
PdfDocumentInterface $pdf,
InvoicePdfBuilder $builder,
) {
$document = $builder->build(
$pdf,
InvoicePdfData::fromInvoiceId(1234),
);
return PdfResponse::download($document, 'invoice-1234.pdf');
}
}

Pomocniki odpowiedzi materializują bajty dokumentu przed zbudowaniem odpowiedzi Laravela. To pomocniki odpowiedzi, a nie generatory działające w tle.

GeneratePdfJob przyjmuje wywoływalny konstruktor oraz ścieżkę wyjścia. Zadanie weryfikuje niebezpieczne ścieżki podczas wykonania. Kod aplikacji powinien mimo to wybrać bezpieczny katalog główny przechowywania dla danego najemcy przed wysłaniem zadania.

<?php
use App\Pdf\Builders\QueuedInvoiceBuilder;
use NextPDF\Laravel\Jobs\GeneratePdfJob;
GeneratePdfJob::dispatch(
outputPath: storage_path('app/pdfs/invoice-1234.pdf'),
builder: [QueuedInvoiceBuilder::class, 'build'],
)->onQueue(config('nextpdf.queue.queue', 'pdf'));

Utrzymuj wywołania zwrotne kolejki w niewielkim rozmiarze. Zamiast przechowywać złożone domknięcia w ładunku kolejki, preferuj zapisywanie trwałego stanu z poziomu nasłuchiwacza zadań aplikacji.

Punkt rozszerzeniaUżywaj go doOgraniczenie
Powiązanie PdfDocumentInterfaceZastąp lub udekoruj mechanizm tworzenia dokumentu, aby ustawić wartości domyślne dla całej aplikacji.Musi zwracać świeżą instancję dokumentu.
DocumentFactoryInterfaceJawnie twórz świeże dokumenty w usługach i testach.Nie buforuj zwróconych dokumentów.
config/nextpdf.phpWartości domyślne, ustawienia kolejki, ustawienia renderera Chrome, punkty zaczepienia podpisywania, TSA, pamięć podręczna OCSP.Traktuj zmienne środowiskowe jako konfigurację wdrożenia, a nie dane wejściowe żądania.
Konstruktor GeneratePdfJobBuduj dokumenty asynchronicznie.Element wywoływalny musi być serializowalny przez transport kolejki Laravela.
Wywołania zwrotne sukcesu lub niepowodzeniaPowiadamianie po wygenerowaniu lub czyszczenie.Utrzymuj idempotentność wywołań zwrotnych i uwzględniaj ich efekty uboczne.
Opcjonalne kontrakty PremiumOsadzacz e-faktur, walidator, profil oraz program uruchamiający Schematron.Rozwiązuj tylko tam, gdzie opcjonalny pakiet jest zainstalowany i licencjonowany.
  1. Zbuduj pierwszy dokument synchronicznie w kontrolerze lub teście funkcjonalnym.
  2. Przenieś kod układu do klasy konstruktora w katalogu app/Pdf/Builders.
  3. Przenieś logikę zapytań i autoryzacji do usługi aplikacyjnej.
  4. Dodaj testy PdfResponse dla nagłówków i nazw plików.
  5. Przenieś powolne generowanie lub generowanie na dużą skalę do GeneratePdfJob.
  6. Dodaj testy kolejki dla serializowanego kontekstu, polityki ścieżki wyjścia oraz obsługi niepowodzeń.
  7. Zmierz pamięć i czas renderowania na reprezentatywnych danych produkcyjnych.
NiepowodzenieGdzie należy je obsłużyćZalecana odpowiedź
Nieprawidłowe żądanie lub nieautoryzowany dokumentKontroler lub polityka.Zwróć standardową odpowiedź autoryzacyjną lub walidacyjną aplikacji.
Brakująca czcionka lub nieprawidłowy obrazTest konstruktora i rejestrowanie w aplikacji.Odrzuć żądanie lub zadanie; nie emituj częściowych plików PDF.
Niebezpieczna ścieżka wyjściaUsługa przechowywania aplikacji oraz GeneratePdfJob.Odrzuć przed wysłaniem zadania i polegaj na walidacji po stronie procesu roboczego jako dodatkowej warstwie zabezpieczeń.
Niepowodzenie podpisywania lub TSAGranica usługi podpisywania.Zdecyduj, czy dokument może pozostać niepodpisany; dla dokumentów regulowanych domyślnie ustaw zachowanie fail-closed.
Przekroczenie limitu czasu kolejkiKonfiguracja procesu roboczego kolejki oraz obserwowalność.Ponawiaj tylko wtedy, gdy konstruktor jest deterministyczny, a ścieżkę wyjścia można bezpiecznie nadpisać.
ZagadnienieWartość domyślnaKiedy zmienić
Nazwa kolejkipdfUżyj dedykowanej kolejki, gdy generowanie konkuruje z zadaniami obsługującymi użytkowników.
Limit czasu zadania120 sekundZwiększaj dopiero po zmierzeniu rozmiaru dokumentu i wydajności procesu roboczego.
Nazwa pliku odpowiedzidocument.pdfUżywaj oczyszczonych identyfikatorów biznesowych.
Rejestr czcionekWspółdzielony i zablokowany po rozgrzaniu.Dodaj preload_fonts dla czcionek używanych na najczęściej wykonywanych ścieżkach.
Rejestr obrazówWspółdzielona pamięć podręczna z limitem.Zmniejsz image_cache_mb dla procesów roboczych z ograniczoną pamięcią.
Fragmentowanie odpowiedzi strumieniowejFragmenty po 64 KB.Nie polegaj na granicach fragmentów; są one szczegółem wyjścia.
  • Testy kontrolera weryfikują Content-Type, Content-Disposition oraz nagłówki obronne.
  • Testy konstruktorów używają deterministycznych obiektów DTO i nie odpytują bazy danych.
  • Testy kolejki weryfikują, że konstruktor otrzymuje świeży dokument.
  • Testy ścieżek obejmują próby przejścia katalogów, opakowania strumieni, bajt zerowy oraz odrzucanie rozszerzeń innych niż .pdf.
  • Testy procesu roboczego renderują reprezentatywne dokumenty pod tym samym limitem pamięci co produkcja.
  • Opcjonalne testy podpisywania obejmują brakujący certyfikat, nieprawidłowe hasło, niedostępność TSA oraz skonfigurowany poziom podpisu.