NextPDF no Laravel: boot e descoberta automática
Visão geral
Seção intitulada “Visão geral”O Laravel descobre automaticamente o NextPdfServiceProvider a partir do composer.json do pacote. O provider registra bindings adiados no container e, em contexto de console, publica o arquivo de configuração. Esta página explica como a descoberta funciona e qual é o ciclo de vida de cada binding.
Instalação
Seção intitulada “Instalação”composer require nextpdf/laravelphp artisan vendor:publish --tag=nextpdf-configComo funciona a descoberta automática do Laravel
Seção intitulada “Como funciona a descoberta automática do Laravel”O pacote declara o provider e o alias de facade no bloco extra.laravel do seu próprio composer.json:
{ "extra": { "laravel": { "providers": [ "NextPDF\\Laravel\\NextPdfServiceProvider" ], "aliases": { "Pdf": "NextPDF\\Laravel\\Facades\\Pdf" } } }}Quando você executa composer require, o Laravel lê esse bloco e então registra o provider e o alias. Você não precisa editar manualmente o config/app.php nem o bootstrap/providers.php. O array extra.laravel.providers registra automaticamente os service providers, e extra.laravel.aliases registra automaticamente os aliases de facade (guia de desenvolvimento de pacotes do Laravel 12,
https://laravel.com/docs/12.x/packages, acessado em 2026-05-18).
Sequência de boot
Seção intitulada “Sequência de boot”NextPdfServiceProvider implementa DeferrableProvider e o ciclo de vida padrão register() / boot().
register()mescla a configuração do pacote sob a chavenextpdf. Em seguida, vincula as entradas do container: registro de fontes, registro de imagens, fábrica de documentos, cliente Hypertext Transfer Protocol (HTTP) compatível com PHP Standards Recommendation 18 (PSR-18), cliente de timestamp, signer, documento e contratos de e-invoice. Cada binding é uma closure, portanto nada pesado é construído aqui.boot()verifica se as extensões PHPmbstringezlibestão carregadas. Ele registra a configuração publicável sob a tagnextpdf-configapenas quandorunningInConsole()é verdadeiro.
Como o provider é adiado, register() só é executado quando você resolve uma das entradas retornadas por provides(). Resolver uma chave de container não relacionada não inicializa o NextPDF.
Bindings do container e tempos de vida
Seção intitulada “Bindings do container e tempos de vida”A PHP Standards Recommendation 11 (PSR-11) permite que duas chamadas get() sucessivas com o mesmo identificador retornem valores diferentes, dependendo da estratégia de binding (PSR-11 §1.1.2). O provider depende desse comportamento por design:
| Chave de binding | Tempo de vida | Observações |
|---|---|---|
FontRegistryInterface (+ alias FontRegistry) | singleton, travado após o warmup | Aquecido a partir de preload_fonts; travado para que nenhuma requisição consiga alterá-lo |
ImageRegistry | singleton | Cache least recently used (LRU) limitado, dimensionado por image_cache_mb; não travado |
DocumentFactoryInterface (+ alias DocumentFactory) | singleton | Sem estado; compartilha os dois registros |
Psr\Http\Client\ClientInterface | singleton | Cliente com proteção contra request-forgery que encapsula um cliente curl; construído a partir de tsa.* |
TsaClient | scoped | null quando tsa.url está vazio |
SignerInterface | factory | null quando a assinatura está desabilitada ou o certificado está vazio |
PdfDocumentInterface (+ alias nextpdf) | factory | Novo NextPDF\Core\Document a cada resolução, com os metadados padrão aplicados |
EmbedderInterface, ValidatorInterface, ProfileInterface, SchematronRunnerInterface | factory | Resolvem para implementações concretas Premium; geram erro na primeira resolução sem nextpdf/premium |
O binding de documento aplica defaults.creator, defaults.language e, quando não está vazio, defaults.author a cada novo documento. Quando pdfa não é nulo, ele habilita PDF/A (Premium). Quando a seção artisan está presente e existe uma classe browser-factory do Chrome, ele aplica a configuração do renderizador Chrome.
has() no container recebe um único identificador de string (PSR-11 §1.1.2). Os contratos de e-invoice estão vinculados, portanto has() retorna verdadeiro para eles mesmo quando o Premium está ausente. A ausência da implementação concreta só gera erro na construção.
Desabilitando a descoberta automática
Seção intitulada “Desabilitando a descoberta automática”Adicione o pacote ao array dont-discover da aplicação e, depois, registre o provider manualmente:
{ "extra": { "laravel": { "dont-discover": ["nextpdf/laravel"] } }}<?php
declare(strict_types=1);
return [ App\Providers\AppServiceProvider::class, NextPDF\Laravel\NextPdfServiceProvider::class,];Ordem de resolução da configuração
Seção intitulada “Ordem de resolução da configuração”Cada chave é resolvida nesta ordem: variável de ambiente → valor publicado em config/nextpdf.php → padrão do pacote mesclado em register(). A maioria das chaves aceita um nome NEXTPDF_* ou um nome de ambiente legado TCPDF_*. Prefira NEXTPDF_*.
Diagnóstico
Seção intitulada “Diagnóstico”php artisan package:discover --ansiUma linha que lista nextpdf/laravel confirma a descoberta. Como o provider é adiado, os próprios bindings só aparecem após a primeira resolução. A linha de descoberta é o sinal correto de sucesso.
Casos extremos & pegadinhas
Seção intitulada “Casos extremos & pegadinhas”- A publicação da configuração é registrada apenas em contexto de console, portanto uma requisição exclusivamente web nunca a aciona. Execute
vendor:publisha partir da interface de linha de comando (CLI). - Além das chaves de registro, fábrica, cliente HTTP, signer, timestamp e documento,
provides()inclui as quatro chaves de contrato de e-invoice. - Uma instalação recém-feita pode parecer inerte até a primeira resolução relevante. Isso faz parte do design de provider adiado, não é uma falha.
Desempenho
Seção intitulada “Desempenho”register() é O(1) porque cria apenas closures. O warmup do registro de fontes é O(f) em fontes pré-carregadas e executa uma vez por processo worker. Adiar o provider mantém o custo de construção do NextPDF fora do fluxo de boot do framework até que um binding seja efetivamente usado.
Notas de segurança
Seção intitulada “Notas de segurança”O design adiado reduz a superfície de ataque no boot. O registro de fontes travado impede que uma requisição altere o estado das fontes de outra em workers de longa duração. Para a cobertura completa de ameaças, consulte /integrations/laravel/security-and-operations/.
Conformidade
Seção intitulada “Conformidade”| Afirmação | Fonte | Cláusula | reference_id |
|---|---|---|---|
| Resoluções sucessivas podem diferir conforme a estratégia de binding | PSR-11 Container | §1.1.2 | |
has() recebe um identificador de string | PSR-11 Container | §1.1.2 |
A documentação oficial de pacotes do Laravel 12 confirma os nomes das chaves de descoberta do Laravel (https://laravel.com/docs/12.x/packages, acessado em 2026-05-18).
Contexto comercial
Seção intitulada “Contexto comercial”As implementações concretas Premium são resolvidas pelas mesmas chaves de binding adiado. Essa capacidade Enterprise opcional não exige alteração de código no pacote Core documentado aqui. Consulte https://nextpdf.dev/get-license/?intent=laravel-signing.
Veja também
Seção intitulada “Veja também”- /integrations/laravel/install/ — instalar e publicar
- /integrations/laravel/overview/ — arquitetura do pacote
- /integrations/laravel/integration/ — guia how-to de wiring de ponta a ponta
- /integrations/laravel/configuration/ — cada chave de configuração