Boot e auto-discovery di NextPDF per Laravel
In sintesi
Sezione intitolata “In sintesi”Laravel rileva automaticamente NextPdfServiceProvider dal file composer.json del pacchetto. Il provider registra binding del container differiti e, in contesto console, pubblica il file di configurazione. Questa pagina descrive il meccanismo di discovery e il ciclo di vita di ciascun binding.
Installazione
Sezione intitolata “Installazione”composer require nextpdf/laravelphp artisan vendor:publish --tag=nextpdf-configCome funziona l’auto-discovery di Laravel
Sezione intitolata “Come funziona l’auto-discovery di Laravel”Il pacchetto dichiara il provider e l’alias della facade nel blocco extra.laravel del suo composer.json:
{ "extra": { "laravel": { "providers": [ "NextPDF\\Laravel\\NextPdfServiceProvider" ], "aliases": { "Pdf": "NextPDF\\Laravel\\Facades\\Pdf" } } }}Quando si esegue composer require, Laravel legge questo blocco e registra il provider e l’alias. Non è necessario modificare manualmente config/app.php o bootstrap/providers.php. L’array extra.laravel.providers registra automaticamente i service provider e extra.laravel.aliases registra automaticamente gli alias delle facade (documentazione per lo sviluppo di pacchetti Laravel 12,
https://laravel.com/docs/12.x/packages, consultata il 2026-05-18).
Sequenza di boot
Sezione intitolata “Sequenza di boot”NextPdfServiceProvider implementa DeferrableProvider e segue il ciclo di vita standard register() / boot().
register()unisce la configurazione del pacchetto sotto la chiavenextpdf. Poi esegue il binding delle voci del container: registry dei font, registry delle immagini, document factory, client HTTP PSR-18, client timestamp, signer, documento e contratti e-invoice. Ogni binding è una closure, quindi in questa fase non viene costruito nulla di oneroso.boot()verifica che le estensioni PHPmbstringezlibsiano caricate. Registra la configurazione pubblicabile con il tagnextpdf-configsolo quandorunningInConsole()restituisce true.
Poiché il provider è differito, register() viene eseguito solo quando si risolve una delle voci restituite da provides(). La risoluzione di una chiave del container non correlata non avvia NextPDF.
Binding del container e cicli di vita
Sezione intitolata “Binding del container e cicli di vita”PSR-11 consente che due chiamate get() successive con lo stesso identificatore restituiscano valori diversi in base alla strategia di binding (PSR-11 §1.1.2). Il provider si basa intenzionalmente su questo comportamento:
| Chiave di binding | Ciclo di vita | Note |
|---|---|---|
FontRegistryInterface (+ alias FontRegistry) | singleton, bloccato dopo il warmup | Precaricato da preload_fonts; bloccato in modo che nessuna richiesta possa modificarlo |
ImageRegistry | singleton | Cache LRU limitata, dimensionata in base a image_cache_mb; non bloccata |
DocumentFactoryInterface (+ alias DocumentFactory) | singleton | Stateless; condivide i due registry |
Psr\Http\Client\ClientInterface | singleton | Client protetto contro la request forgery che incapsula un client curl; costruito da tsa.* |
TsaClient | scoped | null quando tsa.url è vuoto |
SignerInterface | factory | null quando la firma è disabilitata o il certificato è vuoto |
PdfDocumentInterface (+ alias nextpdf) | factory | Nuovo NextPDF\Core\Document per ogni risoluzione, con i metadati predefiniti applicati |
EmbedderInterface, ValidatorInterface, ProfileInterface, SchematronRunnerInterface | factory | Si risolvono nelle implementazioni concrete Premium; generano un errore alla prima risoluzione senza nextpdf/premium |
Il binding del documento applica defaults.creator, defaults.language e (quando non vuoto) defaults.author a ogni nuovo documento. Quando pdfa non è null, abilita PDF/A (Premium). Quando la sezione artisan è presente ed esiste una classe browser-factory per Chrome, applica la configurazione del renderer Chrome.
has() del container accetta un singolo identificatore stringa (PSR-11 §1.1.2). I contratti e-invoice hanno un binding, quindi has() restituisce true anche per questi contratti quando Premium è assente. L’implementazione concreta mancante genera un errore solo al momento della costruzione.
Disabilitazione dell’auto-discovery
Sezione intitolata “Disabilitazione dell’auto-discovery”Aggiungere il pacchetto all’array dont-discover dell’applicazione, quindi registrare il provider manualmente:
{ "extra": { "laravel": { "dont-discover": ["nextpdf/laravel"] } }}<?php
declare(strict_types=1);
return [ App\Providers\AppServiceProvider::class, NextPDF\Laravel\NextPdfServiceProvider::class,];Ordine di risoluzione della configurazione
Sezione intitolata “Ordine di risoluzione della configurazione”Ogni chiave viene risolta in questo ordine: variabile d’ambiente → valore pubblicato in config/nextpdf.php → valore predefinito del pacchetto unito in register(). La maggior parte delle chiavi accetta un nome NEXTPDF_* o un nome d’ambiente legacy TCPDF_*. È preferibile usare NEXTPDF_*.
Diagnostica
Sezione intitolata “Diagnostica”php artisan package:discover --ansiUna riga che elenca nextpdf/laravel conferma il discovery. Poiché il provider è differito, i binding non compaiono fino alla prima risoluzione. La riga di discovery è il segnale di successo corretto.
Casi limite e insidie
Sezione intitolata “Casi limite e insidie”- La pubblicazione della configurazione viene registrata solo in contesto console, quindi una richiesta esclusivamente web non la attiva mai. Eseguire
vendor:publishdalla CLI. - Oltre alle chiavi di registry, factory, client HTTP, signer, timestamp e documento,
provides()include le quattro chiavi dei contratti e-invoice. - Un’installazione appena effettuata può apparire inerte fino alla prima risoluzione pertinente. È il comportamento previsto dal design a provider differito, non un difetto.
Prestazioni
Sezione intitolata “Prestazioni”register() è O(1) — solo closure. Il warmup del registry dei font è O(f) rispetto ai font precaricati e viene eseguito una volta per processo worker. Differire il provider mantiene il costo di costruzione di NextPDF fuori dal percorso di boot del framework finché un binding non viene effettivamente utilizzato.
Note sulla sicurezza
Sezione intitolata “Note sulla sicurezza”Il design differito riduce la superficie di attacco durante il boot. Il registry dei font bloccato impedisce la mutazione dello stato dei font tra richieste nei worker a lunga esecuzione. Per una copertura completa delle minacce, vedere /integrations/laravel/security-and-operations/.
Conformità
Sezione intitolata “Conformità”| Asserzione | Fonte | Clausola | reference_id |
|---|---|---|---|
| Le risoluzioni successive possono differire in base alla strategia di binding | PSR-11 Container | §1.1.2 | |
has() accetta un identificatore stringa | PSR-11 Container | §1.1.2 |
I nomi delle chiavi di discovery di Laravel sono stati verificati a fronte della documentazione ufficiale dei pacchetti per Laravel 12 (https://laravel.com/docs/12.x/packages, consultata il 2026-05-18).
Contesto commerciale
Sezione intitolata “Contesto commerciale”Le implementazioni concrete Premium vengono risolte tramite le stesse chiavi di binding differite. Si tratta di una funzionalità Enterprise facoltativa e il pacchetto Core qui documentato non richiede alcuna modifica al codice per adottarla. Vedere https://nextpdf.dev/get-license/?intent=laravel-signing.
Vedere anche
Sezione intitolata “Vedere anche”- /integrations/laravel/install/ — installazione e pubblicazione
- /integrations/laravel/overview/ — architettura del pacchetto
- /integrations/laravel/integration/ — guida pratica al wiring end-to-end
- /integrations/laravel/configuration/ — ogni chiave di configurazione