Salta ai contenuti

Boot e auto-discovery di NextPDF per Laravel

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.

Terminal window
composer require nextpdf/laravel
php artisan vendor:publish --tag=nextpdf-config

Il pacchetto dichiara il provider e l’alias della facade nel blocco extra.laravel del suo composer.json:

resource: composer.json (extra.laravel)
{
"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).

NextPdfServiceProvider implementa DeferrableProvider e segue il ciclo di vita standard register() / boot().

  1. register() unisce la configurazione del pacchetto sotto la chiave nextpdf. 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.
  2. boot() verifica che le estensioni PHP mbstring e zlib siano caricate. Registra la configurazione pubblicabile con il tag nextpdf-config solo quando runningInConsole() 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.

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 bindingCiclo di vitaNote
FontRegistryInterface (+ alias FontRegistry)singleton, bloccato dopo il warmupPrecaricato da preload_fonts; bloccato in modo che nessuna richiesta possa modificarlo
ImageRegistrysingletonCache LRU limitata, dimensionata in base a image_cache_mb; non bloccata
DocumentFactoryInterface (+ alias DocumentFactory)singletonStateless; condivide i due registry
Psr\Http\Client\ClientInterfacesingletonClient protetto contro la request forgery che incapsula un client curl; costruito da tsa.*
TsaClientscopednull quando tsa.url è vuoto
SignerInterfacefactorynull quando la firma è disabilitata o il certificato è vuoto
PdfDocumentInterface (+ alias nextpdf)factoryNuovo NextPDF\Core\Document per ogni risoluzione, con i metadati predefiniti applicati
EmbedderInterface, ValidatorInterface, ProfileInterface, SchematronRunnerInterfacefactorySi 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.

Aggiungere il pacchetto all’array dont-discover dell’applicazione, quindi registrare il provider manualmente:

resource: application composer.json
{
"extra": {
"laravel": {
"dont-discover": ["nextpdf/laravel"]
}
}
}
resource: bootstrap/providers.php
<?php
declare(strict_types=1);
return [
App\Providers\AppServiceProvider::class,
NextPDF\Laravel\NextPdfServiceProvider::class,
];

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_*.

Terminal window
php artisan package:discover --ansi

Una 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.

  • La pubblicazione della configurazione viene registrata solo in contesto console, quindi una richiesta esclusivamente web non la attiva mai. Eseguire vendor:publish dalla 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.

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.

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/.

AsserzioneFonteClausolareference_id
Le risoluzioni successive possono differire in base alla strategia di bindingPSR-11 Container§1.1.2
has() accetta un identificatore stringaPSR-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).

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.

  • /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