Aller au contenu

Boot et auto-découverte de NextPDF avec Laravel

Laravel découvre automatiquement NextPdfServiceProvider à partir du composer.json du package. Le fournisseur enregistre des liaisons différées dans le conteneur et, en contexte console, publie le fichier de configuration. Cette page explique le mécanisme de découverte et la durée de vie de chaque liaison.

Fenêtre de terminal
composer require nextpdf/laravel
php artisan vendor:publish --tag=nextpdf-config

Le package déclare le fournisseur et l’alias de façade dans le bloc extra.laravel de son propre composer.json :

resource: composer.json (extra.laravel)
{
"extra": {
"laravel": {
"providers": [
"NextPDF\\Laravel\\NextPdfServiceProvider"
],
"aliases": {
"Pdf": "NextPDF\\Laravel\\Facades\\Pdf"
}
}
}
}

Lorsque tu exécutes composer require, Laravel lit ce bloc puis enregistre le fournisseur et l’alias. Tu n’as pas besoin de modifier config/app.php ni bootstrap/providers.php manuellement. Le tableau extra.laravel.providers enregistre automatiquement les fournisseurs de services, et extra.laravel.aliases enregistre automatiquement les alias de façade (guide de développement de packages Laravel 12, https://laravel.com/docs/12.x/packages, consulté le 2026-05-18).

NextPdfServiceProvider implémente à la fois DeferrableProvider et le cycle de vie standard register() / boot().

  1. register() fusionne la configuration du package sous la clé nextpdf. Elle lie ensuite les entrées du conteneur : le registre de polices, le registre d’images, la fabrique de documents, le client HTTP PSR-18, le client d’horodatage, le signataire, le document et les contrats de facturation électronique. Chaque liaison est une closure, donc aucun objet coûteux n’est construit ici.
  2. boot() vérifie que les extensions PHP mbstring et zlib sont chargées. Elle enregistre la configuration publiable sous le tag nextpdf-config uniquement lorsque runningInConsole() renvoie vrai.

Comme le fournisseur est différé, register() ne s’exécute que lorsque tu résous l’une des entrées renvoyées par provides(). Résoudre une clé de conteneur sans lien n’initialise pas NextPDF.

PSR-11 autorise deux appels successifs à get() avec le même identifiant à renvoyer des valeurs différentes selon la stratégie de liaison (PSR-11 §1.1.2). Le fournisseur s’appuie volontairement sur ce comportement :

Clé de liaisonDurée de vieNotes
FontRegistryInterface (+ alias FontRegistry)singleton, verrouillé après le préchauffagePréchauffé à partir de preload_fonts ; verrouillé pour qu’aucune requête ne puisse le muter
ImageRegistrysingletonCache LRU borné, dimensionné par image_cache_mb ; non verrouillé
DocumentFactoryInterface (+ alias DocumentFactory)singletonSans état ; partage les deux registres
Psr\Http\Client\ClientInterfacesingletonClient tenant compte de la falsification de requête, enveloppant un client curl ; construit à partir de tsa.*
TsaClientscopednull quand tsa.url est vide
SignerInterfacefactorynull quand la signature est désactivée ou que le certificat est vide
PdfDocumentInterface (+ alias nextpdf)factoryNouveau NextPDF\Core\Document à chaque résolution, avec les métadonnées par défaut appliquées
EmbedderInterface, ValidatorInterface, ProfileInterface, SchematronRunnerInterfacefactorySe résolvent en implémentations Premium ; erreur à la première résolution sans nextpdf/premium

La liaison du document applique defaults.creator, defaults.language et, lorsqu’il n’est pas vide, defaults.author à chaque nouveau document. Quand pdfa est non null, cela active PDF/A (Premium). Quand la section artisan est présente et qu’une classe de fabrique du navigateur Chrome existe, la configuration du renderer Chrome est appliquée.

Dans le conteneur, has() prend un seul identifiant de type chaîne (PSR-11 §1.1.2). Les contrats de facturation électronique sont liés, donc has() renvoie vrai pour eux, même quand Premium est absent. L’implémentation manquante n’échoue qu’à la construction.

Ajoute le package au tableau dont-discover de l’application, puis enregistre le fournisseur manuellement :

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,
];

Chaque clé se résout dans cet ordre : variable d’environnement → valeur publiée de config/nextpdf.php → valeur par défaut du package fusionnée à register(). La plupart des clés acceptent soit un nom NEXTPDF_*, soit un ancien nom d’environnement TCPDF_*. Préfère NEXTPDF_*.

Fenêtre de terminal
php artisan package:discover --ansi

La présence d’une ligne listant nextpdf/laravel confirme la découverte. Comme le fournisseur est différé, les liaisons elles-mêmes n’apparaissent pas avant leur première résolution. La ligne de découverte est le bon signal de succès.

  • La configuration publiable n’est enregistrée qu’en contexte console, donc une requête purement web ne la déclenche jamais. Lance vendor:publish depuis la CLI.
  • En plus des clés du registre, de la fabrique, du client HTTP, du signataire, de l’horodatage et du document, provides() inclut les quatre clés de contrat de facturation électronique.
  • Une installation neuve peut sembler inerte jusqu’à la première résolution pertinente. C’est le fonctionnement prévu du fournisseur différé, pas un défaut.

register() est en O(1) — uniquement des closures. Le préchauffage du registre de polices est en O(f) sur les polices préchargées et ne s’exécute qu’une seule fois par processus worker. Le fournisseur différé maintient le coût de construction de NextPDF hors du chemin de boot du framework jusqu’à ce qu’une liaison soit réellement utilisée.

La conception différée réduit la surface d’attaque au boot. Le registre de polices verrouillé empêche la mutation de l’état des polices entre requêtes dans les workers de longue durée. Pour l’analyse complète des menaces, voir /integrations/laravel/security-and-operations/.

AffirmationSourceClausereference_id
Des résolutions successives peuvent différer selon la stratégie de liaisonConteneur PSR-11§1.1.2
has() prend un seul identifiant de type chaîneConteneur PSR-11§1.1.2

Les noms des clés de découverte Laravel ont été vérifiés dans la documentation officielle des packages Laravel 12 (https://laravel.com/docs/12.x/packages, consulté le 2026-05-18).

Les implémentations Premium se résolvent via les mêmes clés de liaison différée. Il s’agit d’une capacité Enterprise optionnelle, et le package Core documenté ici n’a besoin d’aucune modification de code pour l’adopter. Voir https://nextpdf.dev/get-license/?intent=laravel-signing.

  • /integrations/laravel/install/ — installation et publication
  • /integrations/laravel/overview/ — architecture du package
  • /integrations/laravel/integration/ — guide de câblage de bout en bout
  • /integrations/laravel/configuration/ — chaque clé de configuration