Ga naar inhoud

Symfony-ontwikkelaarsgids

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.

LaagEigenaarVerantwoordelijkheidHier niet plaatsen
ControllerToepassingAutoriseert de aanvraag, verzamelt invoer en geeft PdfResponse terug.PDF-lay-out die door meerdere use cases wordt gedeeld.
ToepassingsserviceToepassingLaadt domeingegevens en kiest een builder.Logica van de Symfony-containercompiler.
BuilderserviceToepassingImplementeert PdfBuilderInterface voor synchrone documentopbouw of documentopbouw via de wachtrij.Aanvraagobjecten, entity managers of niet-serialiseerbare context.
Symfony-bundlenextpdf/symfonyRegistreert services, de configuratieboom, een optionele uitbreidingspass, responshelpers en Messenger-data transfer objects (DTO’s).Tenantspecifiek opslagbeleid.
Kernenginenextpdf/nextpdfMaakt en serialiseert het document.Symfony-respons- of Messenger-gedrag.
FaseGedragActie van de ontwikkelaar
Opstarten van de bundleNextPdfBundle::build() registreert optionele uitbreidingsdetectie.Laat Symfony de bundle ontdekken of registreer deze in bundles.php.
Laden van de configuratieNextPdfExtension::load() verwerkt de nextpdf:-configuratie en laadt servicedefinities.Houd de configuratie expliciet en omgevingsbewust.
Gebruik van de factoryPdfFactory::create() geeft een nieuw, geconfigureerd document terug.Sla documenten niet op in services.
ControlleruitvoerPdfResponse zet een voltooid document om in een respons.Gebruik de helper in plaats van headers handmatig samen te stellen.
Messenger-dispatchGeneratePdfMessage draagt de builderklasse, het uitvoerpad en serialiseerbare context.Houd de context klein en vriendelijk voor scalaire waarden.
BerichtafhandelingGeneratePdfHandler haalt de builder op via een service locator en slaat het document op.Maak builders deterministisch en idempotent.
PadDoel
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;
}
}
<?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.

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.

UitbreidingspuntGebruik het voorBeperking
Servicedecoratie van PdfFactoryToepassingsstandaarden toepassen voordat documenten de controllers bereiken.Moet de semantiek behouden dat elke aanroep een nieuw document oplevert.
PdfBuilderInterfaceHerbruikbare of in de wachtrij geplaatste documentbuilders definiëren.Moet een Document teruggeven.
OptionalExtensionPassOptionele Artisan- of Premium-functies inschakelen tijdens het compileren.Beschikbaarheid is een compileerstatus van de container, geen aanvraagstatus.
Symfony-configboomStandaardwaarden, PDF/A, renderer-instellingen, handtekening, time-stamping authority (TSA) en Messenger.Ongeldige configuratie hoort te mislukken tijdens het bouwen van de container.
Servicebekabeling van GeneratePdfHandlerBeperken welke builders bereikbaar zijn vanuit berichten in de wachtrij.De service locator hoort alleen goedgekeurde builderservices beschikbaar te stellen.
  1. Voeg een builderservice toe met deterministische invoer.
  2. Gebruik PdfFactory::create() in een controller of service.
  3. Voeg een responstest toe voor de bestandsnaam, het inhoudstype en de headers.
  4. Registreer de builder bij Messenger wanneer hetzelfde document asynchroon moet worden gegenereerd.
  5. Voeg tests voor ongeldige berichten toe voor de klassenaam, het uitvoerpad en de vorm van de context.
  6. Voeg een containercompilatietest toe met een minimale en een productieconfiguratie.
  7. Meet de renderduur en het geheugen onder dezelfde PHP-instellingen als in productie.
FoutWaar deze hoort te worden afgehandeldAanbevolen respons
Ongeldige configuratieContainercompilatie.Laat de deployment mislukken voordat verkeer de app bereikt.
Ontbrekende builderserviceTests van de Messenger-handler en servicetags.Laat het bericht falen en waarschuw het verantwoordelijke team.
Onveilig uitvoerpadBerichtconstructor en opslagbeleid.Wijs het af vóór dispatch; behoud de validatie in de handler als defense in depth.
Optionele uitbreiding niet beschikbaarCompilerpass en factorygedrag.Schakel de optionele functie uit of maak de installatie expliciet.
Serviceconversie- of renderfoutBuildergrens.Fail closed, tenzij de use case een gedocumenteerde fallback heeft.
AandachtspuntStandaardWanneer te overschrijven
Levensduur van de factoryContainerservice.Laat dit zo; de factory is veilig omdat deze nieuwe documenten aanmaakt.
Levensduur van het documentEén werkeenheid.Deel het nooit over aanvragen of berichten heen.
Validatie van het uitvoerpadBerichtconstructor en handler.Voeg tenant- of opslagrootbeperkingen toe in toepassingscode.
Responsbestandsnaamdocument.pdf.Overschrijf deze met opgeschoonde zakelijke identifiers.
Messenger-transportasync.Gebruik een apart transport wanneer het PDF-werk zwaar is.
  • 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.