Symfony-ontwikkelaarsgids
In een oogopslag
Sectie met titel “In een oogopslag”De Symfony-bundle is service-first. Injecteer PdfFactory, roep voor elk Portable Document Format-document (PDF) create() aan en gebruik Messenger-builders voor asynchrone generatie. Je kunt de factory als containerservice laten staan, omdat elke aanroep een nieuw document teruggeeft.
Gebruik deze gids wanneer je controllers, services, Messenger-handlers of uitbreidingspunten op bundleniveau ontwerpt voor nextpdf/symfony.
Architectuurgrens
Sectie met titel “Architectuurgrens”| Laag | Eigenaar | Verantwoordelijkheid | Hier niet plaatsen |
|---|---|---|---|
| Controller | Toepassing | Autoriseert de aanvraag, verzamelt invoer en geeft PdfResponse terug. | PDF-lay-out die door meerdere use cases wordt gedeeld. |
| Toepassingsservice | Toepassing | Laadt domeingegevens en kiest een builder. | Logica van de Symfony-containercompiler. |
| Builderservice | Toepassing | Implementeert PdfBuilderInterface voor synchrone documentopbouw of documentopbouw via de wachtrij. | Aanvraagobjecten, entity managers of niet-serialiseerbare context. |
| Symfony-bundle | nextpdf/symfony | Registreert services, de configuratieboom, een optionele uitbreidingspass, responshelpers en Messenger-data transfer objects (DTO’s). | Tenantspecifiek opslagbeleid. |
| Kernengine | nextpdf/nextpdf | Maakt en serialiseert het document. | Symfony-respons- of Messenger-gedrag. |
Levenscyclus tijdens uitvoering
Sectie met titel “Levenscyclus tijdens uitvoering”| Fase | Gedrag | Actie van de ontwikkelaar |
|---|---|---|
| Opstarten van de bundle | NextPdfBundle::build() registreert optionele uitbreidingsdetectie. | Laat Symfony de bundle ontdekken of registreer deze in bundles.php. |
| Laden van de configuratie | NextPdfExtension::load() verwerkt de nextpdf:-configuratie en laadt servicedefinities. | Houd de configuratie expliciet en omgevingsbewust. |
| Gebruik van de factory | PdfFactory::create() geeft een nieuw, geconfigureerd document terug. | Sla documenten niet op in services. |
| Controlleruitvoer | PdfResponse zet een voltooid document om in een respons. | Gebruik de helper in plaats van headers handmatig samen te stellen. |
| Messenger-dispatch | GeneratePdfMessage draagt de builderklasse, het uitvoerpad en serialiseerbare context. | Houd de context klein en vriendelijk voor scalaire waarden. |
| Berichtafhandeling | GeneratePdfHandler haalt de builder op via een service locator en slaat het document op. | Maak builders deterministisch en idempotent. |
Aanbevolen toepassingsstructuur
Sectie met titel “Aanbevolen toepassingsstructuur”| Pad | Doel |
|---|---|
src/Pdf/Builder/* | Services die PdfBuilderInterface implementeren. |
src/Pdf/Data/* | Kleine DTO’s of arrays die als buildercontext worden gebruikt. |
src/Pdf/Storage/* | Selectie van de opslagroot en beleid voor de uitvoerbestandsnaam. |
src/Controller/* | Ingangspunten voor synchrone responses. |
tests/Pdf/* | Tests voor builder, respons, Messenger en configuratie. |
Geef de voorkeur aan builderservices boven statische helperfuncties. Ze zijn makkelijk te taggen, te decoreren, te testen en vanuit Messenger te gebruiken.
<?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; }}Patroon voor synchrone respons
Sectie met titel “Patroon voor synchrone respons”<?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'); }}Houd de controllercontext klein. Als een builder veel domeinobjecten nodig heeft, verplaats je de orkestratie naar een toepassingsservice en geef je een DTO of genormaliseerde array door aan de builder.
Messenger-patroon
Sectie met titel “Messenger-patroon”GeneratePdfMessage valideert de builderklasse en het uitvoerpad vóór dispatch. De handler valideert het pad opnieuw bij uitvoering.
<?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>', ],));Plaats geen Doctrine-entiteiten, open streams, closures, aanvraagobjecten of serviceobjecten in builderContext.
Uitbreidingspunten
Sectie met titel “Uitbreidingspunten”| Uitbreidingspunt | Gebruik het voor | Beperking |
|---|---|---|
Servicedecoratie van PdfFactory | Toepassingsstandaarden toepassen voordat documenten de controllers bereiken. | Moet de semantiek behouden dat elke aanroep een nieuw document oplevert. |
PdfBuilderInterface | Herbruikbare of in de wachtrij geplaatste documentbuilders definiëren. | Moet een Document teruggeven. |
OptionalExtensionPass | Optionele Artisan- of Premium-functies inschakelen tijdens het compileren. | Beschikbaarheid is een compileerstatus van de container, geen aanvraagstatus. |
| Symfony-configboom | Standaardwaarden, PDF/A, renderer-instellingen, handtekening, time-stamping authority (TSA) en Messenger. | Ongeldige configuratie hoort te mislukken tijdens het bouwen van de container. |
Servicebekabeling van GeneratePdfHandler | Beperken welke builders bereikbaar zijn vanuit berichten in de wachtrij. | De service locator hoort alleen goedgekeurde builderservices beschikbaar te stellen. |
Ontwikkelworkflow
Sectie met titel “Ontwikkelworkflow”- Voeg een builderservice toe met deterministische invoer.
- Gebruik
PdfFactory::create()in een controller of service. - Voeg een responstest toe voor de bestandsnaam, het inhoudstype en de headers.
- Registreer de builder bij Messenger wanneer hetzelfde document asynchroon moet worden gegenereerd.
- Voeg tests voor ongeldige berichten toe voor de klassenaam, het uitvoerpad en de vorm van de context.
- Voeg een containercompilatietest toe met een minimale en een productieconfiguratie.
- Meet de renderduur en het geheugen onder dezelfde PHP-instellingen als in productie.
Foutafhandeling
Sectie met titel “Foutafhandeling”| Fout | Waar deze hoort te worden afgehandeld | Aanbevolen respons |
|---|---|---|
| Ongeldige configuratie | Containercompilatie. | Laat de deployment mislukken voordat verkeer de app bereikt. |
| Ontbrekende builderservice | Tests van de Messenger-handler en servicetags. | Laat het bericht falen en waarschuw het verantwoordelijke team. |
| Onveilig uitvoerpad | Berichtconstructor en opslagbeleid. | Wijs het af vóór dispatch; behoud de validatie in de handler als defense in depth. |
| Optionele uitbreiding niet beschikbaar | Compilerpass en factorygedrag. | Schakel de optionele functie uit of maak de installatie expliciet. |
| Serviceconversie- of renderfout | Buildergrens. | Fail closed, tenzij de use case een gedocumenteerde fallback heeft. |
Veilige standaardwaarden
Sectie met titel “Veilige standaardwaarden”| Aandachtspunt | Standaard | Wanneer te overschrijven |
|---|---|---|
| Levensduur van de factory | Containerservice. | Laat dit zo; de factory is veilig omdat deze nieuwe documenten aanmaakt. |
| Levensduur van het document | Eén werkeenheid. | Deel het nooit over aanvragen of berichten heen. |
| Validatie van het uitvoerpad | Berichtconstructor en handler. | Voeg tenant- of opslagrootbeperkingen toe in toepassingscode. |
| Responsbestandsnaam | document.pdf. | Overschrijf deze met opgeschoonde zakelijke identifiers. |
| Messenger-transport | async. | Gebruik een apart transport wanneer het PDF-werk zwaar is. |
Testchecklist
Sectie met titel “Testchecklist”- Containertests compileren de bundle met een minimale en een productieconfiguratie.
- Responstests controleren de beveiligingsheaders en de afhandeling van de bestandsnaam.
- Messenger-tests controleren of ongeldige paden en ongeldige builderklassennamen mislukken vóór dispatch.
- Handlertests gebruiken een echte builderservice en een tijdelijke uitvoermap.
- Buildertests renderen een representatief document en slaan het op onder productieachtige bestandssysteemrechten.
- Tests voor de optionele uitbreiding dekken dat Artisan niet beschikbaar is, dat Premium niet beschikbaar is en het gedrag van het geconfigureerde PDF/A-profiel.