Pular para o conteúdo

Guia do desenvolvedor Symfony

O pacote Symfony prioriza os serviços. Injete PdfFactory, chame create() para cada documento Portable Document Format (PDF) e use os builders do Messenger para geração assíncrona. Você pode manter a factory como um serviço do container porque cada chamada retorna um documento novo.

Use este guia quando você projetar controllers, serviços, handlers do Messenger ou pontos de extensão no nível do bundle para nextpdf/symfony.

CamadaPertence aResponsabilidadeNão coloque aqui
ControllerAplicaçãoAutorize a requisição, colete a entrada e retorne PdfResponse.Layout de PDF compartilhado entre casos de uso.
Serviço de aplicaçãoAplicaçãoCarregue os dados de domínio e selecione um builder.Lógica do compilador do container Symfony.
Serviço builderAplicaçãoImplemente PdfBuilderInterface para construção de documentos síncrona ou enfileirada.Objetos de requisição, entity managers ou contexto não serializável.
Bundle Symfonynextpdf/symfonyRegistra serviços, a árvore de configuração, o passe de extensão opcional, os helpers de resposta e os data transfer objects (DTOs) do Messenger.Política de armazenamento específica do tenant.
Motor principalnextpdf/nextpdfCria e serializa o documento.Comportamento de resposta do Symfony ou do Messenger.
EtapaComportamentoAção do desenvolvedor
Inicialização do bundleNextPdfBundle::build() registra a detecção de extensões opcionais.Deixe o Symfony descobrir o bundle ou registre-o em bundles.php.
Carregamento de configuraçãoNextPdfExtension::load() processa a configuração nextpdf: e carrega as definições de serviço.Mantenha a configuração explícita e adaptada ao ambiente.
Uso da factoryPdfFactory::create() retorna um documento novo e já configurado.Não armazene documentos em serviços.
Saída do controllerPdfResponse transforma um documento concluído em uma resposta.Use o helper em vez de montar os headers manualmente.
Despacho do MessengerGeneratePdfMessage carrega a classe do builder, o caminho de saída e o contexto serializável.Mantenha o contexto mínimo e composto preferencialmente por valores escalares.
Tratamento de mensagensGeneratePdfHandler resolve o builder a partir de um service locator e salva o documento.Faça os builders determinísticos e idempotentes.
CaminhoFinalidade
src/Pdf/Builder/*Serviços que implementam PdfBuilderInterface.
src/Pdf/Data/*Pequenos DTOs ou arrays usados como contexto do builder.
src/Pdf/Storage/*Seleção da raiz de armazenamento e política de nome do arquivo de saída.
src/Controller/*Pontos de entrada para respostas síncronas.
tests/Pdf/*Testes de builder, de resposta, do Messenger e de configuração.

Prefira serviços builder em vez de funções helper estáticas. Eles são fáceis de marcar com tags, decorar, testar e usar a partir do 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;
}
}
<?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');
}
}

Mantenha o contexto do controller enxuto. Quando um builder precisar de muitos objetos de domínio, mova a orquestração para um serviço de aplicação e passe um DTO ou um array normalizado para o builder.

GeneratePdfMessage valida a classe do builder e o caminho de saída antes do despacho. O handler valida o caminho novamente quando é executado.

<?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>',
],
));

Não coloque entidades do Doctrine, streams abertos, closures, objetos de requisição ou objetos de serviço em builderContext.

Ponto de extensãoUse paraRestrição
PdfFactory decoração de serviçoAplicar os padrões da aplicação antes que os documentos cheguem aos controllers.Deve preservar a semântica de documento novo.
PdfBuilderInterfaceDefinir builders de documentos enfileirados ou reutilizáveis.Deve retornar um Document.
OptionalExtensionPassHabilitar recursos opcionais do Artisan ou Premium em tempo de compilação.A disponibilidade é um estado de compilação do container, não um estado de requisição.
Árvore de configuração do SymfonyPadrões, PDF/A, configurações do renderizador, assinatura, autoridade de carimbo de tempo (TSA) e Messenger.Uma configuração inválida deve falhar durante a construção do container.
GeneratePdfHandler conexão de serviçoRestringir quais builders são acessíveis a partir de mensagens enfileiradas.O service locator deve expor apenas os serviços builder aprovados.
  1. Adicione um serviço builder com entrada determinística.
  2. Use PdfFactory::create() em um controller ou serviço.
  3. Adicione um teste de resposta para o nome do arquivo, o content type e os headers.
  4. Registre o builder no Messenger quando o mesmo documento precisar ser gerado de forma assíncrona.
  5. Adicione testes de mensagem inválida para o nome da classe, o caminho de saída e o formato do contexto.
  6. Adicione um teste de compilação do container com configuração mínima e de produção.
  7. Meça o tempo de renderização e a memória sob as mesmas configurações de PHP usadas em produção.
FalhaOnde deve ser tratadaResposta recomendada
Configuração inválidaCompilação do container.Faça o deploy falhar antes que o tráfego chegue à aplicação.
Serviço builder ausenteTestes do handler do Messenger e tags de serviço.Faça a mensagem falhar e alerte a equipe responsável.
Caminho de saída inseguroConstrutor da mensagem e política de armazenamento.Rejeite-o antes do despacho; mantenha a validação no handler como defesa em profundidade.
Extensão opcional indisponívelPasse do compilador e comportamento da factory.Desabilite o recurso opcional ou torne a instalação explícita.
Falha de conversão de serviço ou de renderizaçãoFronteira do builder.Falhe de forma fechada, a menos que o caso de uso tenha um fallback documentado.
AspectoPadrãoQuando sobrescrever
Tempo de vida da factoryServiço do container.Mantenha assim; a factory é segura porque cria documentos novos.
Tempo de vida do documentoUma unidade de trabalho.Nunca compartilhe entre requisicoes ou mensagens.
Validação do caminho de saídaConstrutor da mensagem e handler.Adicione restrições de tenant ou de raiz de armazenamento no código da aplicação.
Nome do arquivo de respostadocument.pdf.Sobrescreva com identificadores de negócio higienizados.
Transporte do Messengerasync.Use um transporte dedicado quando o trabalho de PDF for pesado.
  • Os testes de container compilam o bundle com configuração mínima e de produção.
  • Os testes de resposta verificam os headers de segurança e o tratamento do nome do arquivo.
  • Os testes do Messenger verificam que caminhos inválidos e nomes de classe de builder inválidos falham antes do despacho.
  • Os testes do handler usam um serviço builder real e um diretório de saída temporário.
  • Os testes de builder renderizam um documento representativo e o salvam com permissões de sistema de arquivos semelhantes às de produção.
  • Os testes de extensão opcional cobrem Artisan indisponível, Premium indisponível e o comportamento do perfil PDF/A configurado.