Przewodnik dla dewelopera Symfony
W skrócie
Dział zatytułowany „W skrócie”Pakiet Symfony opiera się przede wszystkim na usługach. Wstrzykuj PdfFactory, wywołuj create() dla każdego dokumentu Portable Document Format (PDF) i używaj konstruktorów Messenger do generowania asynchronicznego. Możesz pozostawić fabrykę jako usługę kontenera, ponieważ każde wywołanie zwraca nowy dokument.
Korzystaj z tego przewodnika przy projektowaniu kontrolerów, usług, procedur obsługi Messenger lub punktów rozszerzeń na poziomie pakietu dla nextpdf/symfony.
Granica architektury
Dział zatytułowany „Granica architektury”| Warstwa | Należy do | Odpowiedzialność | Nie umieszczaj tutaj |
|---|---|---|---|
| Kontroler | Aplikacja | Autoryzacja żądania, zebranie danych wejściowych i zwrócenie PdfResponse. | Współdzielony układ PDF dla różnych przypadków użycia. |
| Usługa aplikacji | Aplikacja | Wczytanie danych domenowych i wybór konstruktora. | Logika kompilatora kontenera Symfony. |
| Usługa konstruktora | Aplikacja | Implementacja PdfBuilderInterface dla synchronicznego lub kolejkowanego tworzenia dokumentów. | Obiekty żądania, menedżery encji ani kontekst nieserializowalny. |
| Pakiet Symfony | nextpdf/symfony | Rejestracja usług, drzewa konfiguracji, opcjonalnego przejścia rozszerzającego, pomocników odpowiedzi oraz obiektów transferu danych (DTO) Messenger. | Polityka przechowywania specyficzna dla najemcy. |
| Silnik rdzeniowy | nextpdf/nextpdf | Tworzenie i serializacja dokumentu. | Zachowanie odpowiedzi Symfony ani Messenger. |
Cykl życia w czasie wykonywania
Dział zatytułowany „Cykl życia w czasie wykonywania”| Etap | Zachowanie | Działanie dewelopera |
|---|---|---|
| Rozruch pakietu | NextPdfBundle::build() rejestruje mechanizm wykrywania opcjonalnych rozszerzeń. | Pozwól Symfony wykryć pakiet lub zarejestruj go w bundles.php. |
| Wczytanie konfiguracji | NextPdfExtension::load() przetwarza konfigurację nextpdf: i wczytuje definicje usług. | Dbaj, aby konfiguracja była jawna i uwzględniała środowisko. |
| Użycie fabryki | PdfFactory::create() zwraca nowy, skonfigurowany dokument. | Nie przechowuj dokumentów w usługach. |
| Wynik kontrolera | PdfResponse przekształca gotowy dokument w odpowiedź. | Używaj pomocnika zamiast ręcznego składania nagłówków. |
| Wysłanie przez Messenger | GeneratePdfMessage przekazuje klasę konstruktora, ścieżkę wyjściową oraz serializowalny kontekst. | Utrzymuj kontekst minimalny i oparty na wartościach skalarnych. |
| Obsługa wiadomości | GeneratePdfHandler pobiera konstruktor z lokalizatora usług i zapisuje dokument. | Dbaj, aby konstruktory były deterministyczne i idempotentne. |
Zalecana struktura aplikacji
Dział zatytułowany „Zalecana struktura aplikacji”| Ścieżka | Przeznaczenie |
|---|---|
src/Pdf/Builder/* | Usługi implementujące PdfBuilderInterface. |
src/Pdf/Data/* | Niewielkie obiekty DTO lub tablice używane jako kontekst konstruktora. |
src/Pdf/Storage/* | Wybór katalogu głównego przechowywania oraz polityka nazw plików wyjściowych. |
src/Controller/* | Punkty wejścia dla odpowiedzi synchronicznych. |
tests/Pdf/* | Testy konstruktorów, odpowiedzi, Messenger i konfiguracji. |
Preferuj konstruktory jako usługi zamiast statycznych funkcji pomocniczych. Łatwo dodawać do nich tagi, dekorować je, testować i wykorzystywać z poziomu Messenger.
<?php
namespace App\Pdf\Builder;
use NextPDF\Core\Document;use NextPDF\Symfony\Message\PdfBuilderInterface;
final readonly class InvoicePdfBuilder implements PdfBuilderInterface{ public function build(Document $document, array $context): Document { $document->setTitle((string) $context['title']) ->addPage() ->writeHtml((string) $context['html']);
return $document; }}Wzorzec synchronicznej odpowiedzi
Dział zatytułowany „Wzorzec synchronicznej odpowiedzi”<?php
namespace App\Controller;
use App\Pdf\Builder\InvoicePdfBuilder;use NextPDF\Symfony\Http\PdfResponse;use NextPDF\Symfony\Service\PdfFactory;
final readonly class InvoiceController{ public function __invoke( PdfFactory $factory, InvoicePdfBuilder $builder, ) { $document = $builder->build($factory->create(), [ 'title' => 'Invoice 1234', 'html' => '<h1>Invoice 1234</h1>', ]);
return PdfResponse::download($document, 'invoice-1234.pdf'); }}Kontekst kontrolera powinien być niewielki. Jeśli konstruktor potrzebuje wielu obiektów domenowych, przenieś orkiestrację do usługi aplikacji i przekaż konstruktorowi obiekt DTO albo znormalizowaną tablicę.
Wzorzec Messenger
Dział zatytułowany „Wzorzec Messenger”GeneratePdfMessage waliduje klasę konstruktora i ścieżkę wyjściową przed wysłaniem wiadomości. Procedura obsługi ponownie waliduje ścieżkę podczas wykonywania.
<?php
use App\Pdf\Builder\InvoicePdfBuilder;use NextPDF\Symfony\Message\GeneratePdfMessage;
$bus->dispatch(new GeneratePdfMessage( builderClass: InvoicePdfBuilder::class, outputPath: $projectDir . '/var/pdfs/invoice-1234.pdf', builderContext: [ 'title' => 'Invoice 1234', 'html' => '<h1>Invoice 1234</h1>', ],));Nie umieszczaj encji Doctrine, otwartych strumieni, domknięć, obiektów żądania ani obiektów usług w builderContext.
Punkty rozszerzeń
Dział zatytułowany „Punkty rozszerzeń”| Punkt rozszerzenia | Używaj go do | Ograniczenie |
|---|---|---|
Dekorowanie usługi PdfFactory | Stosowanie domyślnych ustawień aplikacji, zanim dokumenty trafią do kontrolerów. | Musi zachować semantykę nowego dokumentu. |
PdfBuilderInterface | Definiowanie konstruktorów dokumentów przeznaczonych do kolejki lub wielokrotnego użytku. | Musi zwracać Document. |
OptionalExtensionPass | Włączanie opcjonalnych funkcji Artisan lub Premium podczas kompilacji. | Dostępność jest stanem kompilacji kontenera, a nie stanem żądania. |
| Drzewo konfiguracji Symfony | Ustawienia domyślne, PDF/A, ustawienia mechanizmu renderowania, podpis, urząd znacznika czasu (TSA) oraz Messenger. | Nieprawidłowa konfiguracja powinna spowodować niepowodzenie podczas budowania kontenera. |
Podłączenie usługi GeneratePdfHandler | Ograniczanie, które konstruktory są dostępne z kolejkowanych wiadomości. | Lokalizator usług powinien udostępniać wyłącznie zatwierdzone usługi konstruktorów. |
Przepływ pracy programistycznej
Dział zatytułowany „Przepływ pracy programistycznej”- Dodaj usługę konstruktora z deterministycznymi danymi wejściowymi.
- Użyj
PdfFactory::create()w kontrolerze lub usłudze. - Dodaj test odpowiedzi obejmujący nazwę pliku, typ treści i nagłówki.
- Zarejestruj konstruktor w Messenger, gdy ten sam dokument musi być generowany asynchronicznie.
- Dodaj testy nieprawidłowych wiadomości obejmujące nazwę klasy, ścieżkę wyjściową i kształt kontekstu.
- Dodaj test kompilacji kontenera dla konfiguracji minimalnej i produkcyjnej.
- Zmierz czas renderowania i zużycie pamięci przy takich samych ustawieniach PHP jak w środowisku produkcyjnym.
Obsługa awarii
Dział zatytułowany „Obsługa awarii”| Awaria | Gdzie powinna zostać obsłużona | Zalecana reakcja |
|---|---|---|
| Nieprawidłowa konfiguracja | Kompilacja kontenera. | Przerwij wdrożenie, zanim ruch dotrze do aplikacji. |
| Brakująca usługa konstruktora | Testy procedury obsługi Messenger i znaczniki usług. | Niech wiadomość zakończy się niepowodzeniem i powiadom odpowiedzialny zespół. |
| Niebezpieczna ścieżka wyjściowa | Konstruktor wiadomości i polityka przechowywania. | Odrzuć ją przed wysłaniem; zachowaj walidację w procedurze obsługi jako obronę w głąb. |
| Opcjonalne rozszerzenie niedostępne | Przejście kompilatora i zachowanie fabryki. | Wyłącz opcjonalną funkcję lub uczyń jej instalację jawną. |
| Niepowodzenie konwersji usługi lub renderowania | Granica konstruktora. | Działaj w trybie fail-closed, chyba że przypadek użycia ma udokumentowany mechanizm zastępczy. |
Bezpieczne ustawienia domyślne
Dział zatytułowany „Bezpieczne ustawienia domyślne”| Zagadnienie | Domyślnie | Kiedy nadpisać |
|---|---|---|
| Czas życia fabryki | Usługa kontenera. | Zachowaj to; fabryka jest bezpieczna, ponieważ tworzy nowe dokumenty. |
| Czas życia dokumentu | Jedna jednostka pracy. | Nigdy nie współdziel dokumentu między żądaniami ani wiadomościami. |
| Walidacja ścieżki wyjściowej | Konstruktor wiadomości i procedura obsługi. | Dodaj w kodzie aplikacji ograniczenia dotyczące najemcy lub katalogu głównego przechowywania. |
| Nazwa pliku odpowiedzi | document.pdf. | Nadpisuj przy użyciu oczyszczonych identyfikatorów biznesowych. |
| Transport Messenger | async. | Użyj dedykowanego transportu, gdy generowanie PDF jest obciążające. |
Lista kontrolna testów
Dział zatytułowany „Lista kontrolna testów”- Testy kontenera kompilują pakiet z konfiguracją minimalną i produkcyjną.
- Testy odpowiedzi sprawdzają nagłówki bezpieczeństwa i obsługę nazwy pliku.
- Testy Messenger sprawdzają, czy nieprawidłowe ścieżki i nieprawidłowe nazwy klas konstruktorów kończą się niepowodzeniem przed wysłaniem.
- Testy procedury obsługi korzystają z rzeczywistej usługi konstruktora i tymczasowego katalogu wyjściowego.
- Testy konstruktora renderują reprezentatywny dokument i zapisują go z uprawnieniami systemu plików zbliżonymi do produkcyjnych.
- Testy opcjonalnych rozszerzeń obejmują zachowanie przy niedostępnym Artisan, niedostępnym Premium oraz skonfigurowanym profilu PDF/A.