Przewodnik dewelopera po Laravelu
W skrócie
Dział zatytułowany „W skrócie”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.
Granica architektury
Dział zatytułowany „Granica architektury”| Warstwa | Właściciel | Odpowiedzialność | Czego tu nie umieszczać |
|---|---|---|---|
| Kontroler | Aplikacja | Autoryzuje żądanie, wybiera konstruktor dokumentu i zwraca odpowiedź. | Reguły układu PDF współdzielone między przypadkami użycia. |
| Usługa aplikacyjna | Aplikacja | Zbiera dane domenowe i wywołuje kod budujący dokument. | Logika startowa kontenera lub konfiguracja pakietu. |
| Konstruktor dokumentu | Aplikacja | Przekłada dane domenowe na wywołania dokumentu NextPDF. | Obiekty żądań, logika zapytań Eloquent lub szczegóły transportu kolejki. |
| Integracja z Laravelem | nextpdf/laravel | Wiąże fabryki, rejestry, podpisującego, klienta TSA, fasadę, odpowiedzi oraz zadanie kolejkowe. | Ścieżki przechowywania specyficzne dla biznesu lub polityka najemcy. |
| Silnik podstawowy | nextpdf/nextpdf | Buduje i serializuje plik PDF. | Polityka odpowiedzi, kolejki lub systemu plików Laravela. |
Cykl życia podczas wykonania
Dział zatytułowany „Cykl życia podczas wykonania”| Etap | Zachowanie | Działanie dewelopera |
|---|---|---|
| Rejestracja dostawcy usług | NextPdfServiceProvider::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 dokumentu | Fasada 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ści | Kod aplikacji wywołuje bazowe API dokumentu przez fasadę lub wstrzyknięty dokument. | Trzymaj pobieranie danych domenowych poza konstruktorem dokumentu. |
| Wyjście końcowe | PdfResponse emituje wyjście HTTP albo dokument jest zapisywany na dysku. | Dla każdego dokumentu wybierz jedną końcową ścieżkę wyjścia. |
| Wykonanie w kolejce | GeneratePdfJob odbudowuje dokument w procesie roboczym i ponownie weryfikuje ścieżkę wyjścia. | Przekazuj kontekst skalarny i utrzymuj idempotentność wywołań zwrotnych. |
Zalecana struktura aplikacji
Dział zatytułowany „Zalecana struktura aplikacji”| Ścieżka | Przeznaczenie |
|---|---|
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; }}Wzorzec odpowiedzi synchronicznej
Dział zatytułowany „Wzorzec odpowiedzi synchronicznej”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.
Wzorzec kolejki
Dział zatytułowany „Wzorzec kolejki”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.
Punkty rozszerzeń
Dział zatytułowany „Punkty rozszerzeń”| Punkt rozszerzenia | Używaj go do | Ograniczenie |
|---|---|---|
Powiązanie PdfDocumentInterface | Zastąp lub udekoruj mechanizm tworzenia dokumentu, aby ustawić wartości domyślne dla całej aplikacji. | Musi zwracać świeżą instancję dokumentu. |
DocumentFactoryInterface | Jawnie twórz świeże dokumenty w usługach i testach. | Nie buforuj zwróconych dokumentów. |
config/nextpdf.php | Wartoś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 GeneratePdfJob | Buduj dokumenty asynchronicznie. | Element wywoływalny musi być serializowalny przez transport kolejki Laravela. |
| Wywołania zwrotne sukcesu lub niepowodzenia | Powiadamianie po wygenerowaniu lub czyszczenie. | Utrzymuj idempotentność wywołań zwrotnych i uwzględniaj ich efekty uboczne. |
| Opcjonalne kontrakty Premium | Osadzacz e-faktur, walidator, profil oraz program uruchamiający Schematron. | Rozwiązuj tylko tam, gdzie opcjonalny pakiet jest zainstalowany i licencjonowany. |
Przepływ pracy dewelopera
Dział zatytułowany „Przepływ pracy dewelopera”- Zbuduj pierwszy dokument synchronicznie w kontrolerze lub teście funkcjonalnym.
- Przenieś kod układu do klasy konstruktora w katalogu
app/Pdf/Builders. - Przenieś logikę zapytań i autoryzacji do usługi aplikacyjnej.
- Dodaj testy
PdfResponsedla nagłówków i nazw plików. - Przenieś powolne generowanie lub generowanie na dużą skalę do
GeneratePdfJob. - Dodaj testy kolejki dla serializowanego kontekstu, polityki ścieżki wyjścia oraz obsługi niepowodzeń.
- Zmierz pamięć i czas renderowania na reprezentatywnych danych produkcyjnych.
Obsługa niepowodzeń
Dział zatytułowany „Obsługa niepowodzeń”| Niepowodzenie | Gdzie należy je obsłużyć | Zalecana odpowiedź |
|---|---|---|
| Nieprawidłowe żądanie lub nieautoryzowany dokument | Kontroler lub polityka. | Zwróć standardową odpowiedź autoryzacyjną lub walidacyjną aplikacji. |
| Brakująca czcionka lub nieprawidłowy obraz | Test konstruktora i rejestrowanie w aplikacji. | Odrzuć żądanie lub zadanie; nie emituj częściowych plików PDF. |
| Niebezpieczna ścieżka wyjścia | Usł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 TSA | Granica usługi podpisywania. | Zdecyduj, czy dokument może pozostać niepodpisany; dla dokumentów regulowanych domyślnie ustaw zachowanie fail-closed. |
| Przekroczenie limitu czasu kolejki | Konfiguracja procesu roboczego kolejki oraz obserwowalność. | Ponawiaj tylko wtedy, gdy konstruktor jest deterministyczny, a ścieżkę wyjścia można bezpiecznie nadpisać. |
Bezpieczne wartości domyślne
Dział zatytułowany „Bezpieczne wartości domyślne”| Zagadnienie | Wartość domyślna | Kiedy zmienić |
|---|---|---|
| Nazwa kolejki | pdf | Użyj dedykowanej kolejki, gdy generowanie konkuruje z zadaniami obsługującymi użytkowników. |
| Limit czasu zadania | 120 sekund | Zwiększaj dopiero po zmierzeniu rozmiaru dokumentu i wydajności procesu roboczego. |
| Nazwa pliku odpowiedzi | document.pdf | Używaj oczyszczonych identyfikatorów biznesowych. |
| Rejestr czcionek | Współdzielony i zablokowany po rozgrzaniu. | Dodaj preload_fonts dla czcionek używanych na najczęściej wykonywanych ścieżkach. |
| Rejestr obrazów | Współdzielona pamięć podręczna z limitem. | Zmniejsz image_cache_mb dla procesów roboczych z ograniczoną pamięcią. |
| Fragmentowanie odpowiedzi strumieniowej | Fragmenty po 64 KB. | Nie polegaj na granicach fragmentów; są one szczegółem wyjścia. |
Lista kontrolna testów
Dział zatytułowany „Lista kontrolna testów”- Testy kontrolera weryfikują
Content-Type,Content-Dispositionoraz 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.