Pular para o conteúdo

Visão geral da integração do NextPDF com o Laravel

O pacote nextpdf/laravel conecta o motor de PDF do NextPDF à sua aplicação Laravel 12 e registra os bindings do contêiner para você. Ele inclui uma facade Pdf, um helper HTTP PdfResponse e um GeneratePdfJob para filas. O Laravel descobre o pacote automaticamente, portanto você não precisa registrá-lo manualmente.

Terminal window
composer require nextpdf/laravel

A restrição do Composer é nextpdf/core: ^3.0 || ^5.2. O pacote também requer laravel/framework: ^12.0 e php: >=8.4 <9.0. Para ver o procedimento completo, incluindo a publicação da configuração e extensões opcionais, consulte /integrations/laravel/install/.

O pacote atua entre o service container do Laravel e o core do NextPDF, que é independente de framework. Ele não reimplementa a geração de PDF. Em vez disso, adapta o modelo NextPDF\Core\Document do core ao ciclo de vida, à configuração, às filas e à camada HTTP do Laravel.

O diagrama abaixo mostra o caminho de uma requisição que parte do código da aplicação, passa pelo pacote e chega aos registries compartilhados do core.

NextPDF Laravel request and render flowA request resolves a fresh document from the container, which the package adapts onto the shared font and image registries before HTTP or queue output.

Your Laravel app

Pdf facade

Laravel service container

NextPdfServiceProvider (deferred)

DocumentFactory (singleton)

Document (fresh per resolve)

FontRegistry (singleton, locked)

ImageRegistry (singleton, LRU)

PdfResponse (HTTP)

GeneratePdfJob (queue worker)

NextPDF Laravel request and render flow

O mapa de autoload tem uma única entrada PSR-4. A PSR-4 é a PHP Standard Recommendation para autoload, e o prefixo NextPDF\Laravel\ mapeia para src/Laravel/. Na PSR-4, um prefixo de namespace corresponde a um diretório base, e o restante do nome da classe mapeia para um caminho de arquivo dentro desse diretório (PSR-4 §3). Quatro classes de produção ficam sob esse prefixo:

  • NextPDF\Laravel\NextPdfServiceProvider — registra os bindings e publica a configuração.
  • NextPDF\Laravel\Facades\Pdf — um proxy estático que resolve um novo documento a partir do contêiner.
  • NextPDF\Laravel\Http\PdfResponse — cria respostas PDF inline, de download e via stream com um conjunto fixo de cabeçalhos de segurança.
  • NextPDF\Laravel\Jobs\GeneratePdfJob — um job que pode ser enfileirado para construir e salvar um PDF em um worker.

O service provider implementa DeferrableProvider, portanto registra os bindings apenas quando você resolve uma das entradas anunciadas. Esse adiamento mantém enxuto o fluxo de boot do framework. O método provides() do provider lista as entradas adiadas, e o contêiner lê essa lista para mapear cada chave de volta ao provider.

A resolução segue o contrato do contêiner: quando existe um binding, resolver o identificador retorna a entrada registrada. A PSR-11 é a PHP Standard Recommendation para interoperabilidade de contêineres, e ela observa que duas chamadas sucessivas de get() com o mesmo identificador podem retornar valores diferentes, dependendo da estratégia de binding (PSR-11 §1.1.2). O NextPDF depende desse comportamento de forma intencional. Os registries são singletons, portanto cada resolução retorna a mesma instância. Os documentos usam binding por factory, portanto cada resolução retorna uma nova instância. Para a tabela completa de tempo de vida dos bindings, consulte /integrations/laravel/boot-and-discovery/.

A arquitetura foi projetada para workers de longa duração, como Octane, RoadRunner e Swoole. O registry de fontes é um singleton com tempo de vida do processo: o pacote o aquece uma vez e depois o trava, de modo que nenhuma requisição possa alterar o estado compartilhado das fontes. O registry de imagens é um singleton com tempo de vida do processo e um cache limitado do tipo least-recently-used (LRU). Como o pacote sempre cria cada documento a partir do DocumentFactory, o estado mutável de uma requisição nunca vaza para outra.

ClassePonto de entrada públicoRetornaFinalidade
NextPdfServiceProviderregister(), boot(), provides()void / arrayBindings do contêiner, publicação da configuração, lista de entradas adiadas
Facades\Pdfproxy estático (addPage(), cell(), save(), …)static / mixedResolve PdfDocumentInterface a cada chamada
Http\PdfResponseinline(), download(), streamInline(), streamDownload()Response / StreamedResponseRespostas HTTP com cabeçalhos do Open Worldwide Application Security Project (OWASP)
Jobs\GeneratePdfJobdispatch(), handle(), then(), catch(), failed()PendingDispatch / void / selfGeração de PDF enfileirada

Chaves de contêiner vinculadas pelo provider:

ChaveTempo de vidaResolve para
NextPDF\Contracts\FontRegistryInterface (alias FontRegistry)singleton, travadoNextPDF\Typography\FontRegistry
NextPDF\Graphics\ImageRegistrysingleton, limitado por LRUImageRegistry
NextPDF\Contracts\DocumentFactoryInterface (alias DocumentFactory)singletonNextPDF\Core\DocumentFactory
Psr\Http\Client\ClientInterfacesingletonSecurityAwareHttpClient envolvendo CurlHttpClient
NextPDF\Security\Timestamp\TsaClientscopedTsaClient ou null quando não há URL de autoridade de carimbo do tempo (TSA)
NextPDF\Contracts\SignerInterfacefactoryDigitalSigner ou null quando a assinatura está desabilitada
NextPDF\Contracts\PdfDocumentInterface (alias nextpdf)factoryNextPDF\Core\Document
NextPDF\Contracts\EInvoice\{Embedder,Validator,Profile,SchematronRunner}Interfacefactoryresolve somente quando nextpdf/premium está instalado
resource: README.md Quick Start (verified against src/Laravel/Facades/Pdf.php)
<?php
declare(strict_types=1);
use NextPDF\Laravel\Facades\Pdf;
Pdf::addPage();
Pdf::cell(0, 10, 'Hello from Laravel', newLine: true);
Pdf::save(storage_path('app/hello.pdf'));

Para um exemplo executável no escopo de um controller, consulte /integrations/laravel/quickstart/.

O padrão de produção resolve o contrato do documento a partir do contêiner, em vez da facade, o que mantém o ponto de chamada explícito e testável. Para o controller completo, incluindo injeção de dependência (DI) e tratamento de erros, consulte /integrations/laravel/production-usage/.

resource: src/Laravel/Http/PdfResponse.php (download factory)
<?php
declare(strict_types=1);
use NextPDF\Contracts\PdfDocumentInterface;
use NextPDF\Laravel\Http\PdfResponse;
$document = app(PdfDocumentInterface::class);
$document->addPage();
$document->cell(0, 10, 'Invoice', newLine: true);
return PdfResponse::download($document, 'invoice.pdf');
  • O provider é adiado, portanto resolver uma chave de contêiner sem relação não inicializa o NextPDF. Os bindings aparecem apenas quando você solicita uma das entradas de provides().
  • SignerInterface e TsaClient resolvem para null por design quando você não configurou a assinatura ou a autoridade de carimbo do tempo. O código deve verificar se o resultado é nulo; não presuma que existe uma instância.
  • Os bindings de contrato de e-invoice são sempre registrados, mas resolvem para implementações concretas do Premium que existem apenas quando nextpdf/premium está instalado. Resolvê-los sem o Premium gera um erro de classe não encontrada, e o erro surge na primeira resolução, não no boot.
  • A facade retorna um documento novo a cada resolução. Considere duas chamadas estáticas Pdf:: na mesma requisição separadas por Pdf::clearResolvedInstances(): as chamadas operam em documentos diferentes.

O registro do provider é executado em tempo O(1). O provider registra closures e não constrói objetos pesados, portanto o custo de construção é adiado para a primeira resolução. O aquecimento do registry de fontes é executado em tempo O(f), em que f é o número de arquivos de fonte pré-carregados, e ocorre uma vez por processo worker. Isso amortiza a latência da primeira requisição em workers de longa duração. O orçamento de memória por página desta visão geral é registrado no campo de front-matter performance_budget.

PdfResponse aplica um conjunto fixo de cabeçalhos definido pelo Open Worldwide Application Security Project (OWASP). O conjunto inclui X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Content-Security-Policy: default-src 'none', X-Robots-Tag e Referrer-Policy: no-referrer. O GeneratePdfJob valida o caminho de saída no worker, o que mitiga payloads serializados adulterados. Para ver o modelo de ameaças completo e a configuração de deployment, consulte /integrations/laravel/security-and-operations/.

AfirmaçãoFonteCláusulareference_id
Semântica de resolução / tempo de vida do contêinerPSR-11 Container§1.1.2
Mapeamento de prefixo de autoload da PSR-4PSR-4 Autoloader§3

Quando nextpdf/premium está instalado, o mesmo provider expõe mais recursos: assinatura digital (PAdES B-B), arquivamento PDF/A e bindings de contrato de e-invoice. Ele os expõe pelas mesmas chaves de contêiner, portanto o pacote Core documentado aqui não precisa de nenhuma alteração de código para adotar esses recursos. Para saber mais, consulte https://nextpdf.dev/get-license/?intent=laravel-signing.

  • /integrations/laravel/install/ — procedimento de instalação e extensões opcionais
  • /integrations/laravel/quickstart/ — exemplo executável de controller
  • /integrations/laravel/configuration/ — cada chave de configuração, verificada em relação a config/nextpdf.php
  • /integrations/laravel/production-usage/ — controller integrado por DI, tratamento de erros, enfileiramento
  • /integrations/laravel/boot-and-discovery/ — descoberta automática e tempos de vida dos bindings
  • /integrations/laravel/security-and-operations/ — modelo de ameaças e configuração de deployment