Aller au contenu

Vue d'ensemble de l'intégration Laravel pour NextPDF

Le package nextpdf/laravel relie le moteur de rendu PDF NextPDF à une application Laravel 12 et enregistre pour toi les liaisons de conteneur. Il fournit une façade Pdf, un assistant HTTP PdfResponse et un job en file d’attente GeneratePdfJob. Laravel découvre automatiquement le package, donc tu n’as pas besoin de l’enregistrer manuellement.

Fenêtre de terminal
composer require nextpdf/laravel

La contrainte Composer est nextpdf/core: ^3.0 || ^5.2. Le package requiert aussi laravel/framework: ^12.0 et php: >=8.4 <9.0. Pour la procédure complète, y compris la publication de la configuration et les extensions optionnelles, consulte /integrations/laravel/install/.

Le package s’insère dans la couche étroite entre le conteneur de services Laravel et le cœur NextPDF, indépendant du framework. Il ne réimplémente pas la génération de PDF. À la place, il adapte le modèle du cœur NextPDF\Core\Document au cycle de vie, à la configuration, à la mise en file d’attente et aux couches HTTP de Laravel.

Le schéma ci-dessous montre comment une requête part du code de ton application, traverse le package, puis arrive dans les registres centraux partagés.

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

Le mapping d’autoload contient une seule entrée PSR-4. PSR-4 est la PHP Standard Recommendation pour l’autoload, et son préfixe NextPDF\Laravel\ correspond à src/Laravel/. Sous PSR-4, un préfixe d’espace de noms correspond à un répertoire de base, et le reste du nom de classe correspond alors à un chemin de fichier sous ce répertoire (PSR-4 §3). Quatre classes de production se trouvent sous ce préfixe :

  • NextPDF\Laravel\NextPdfServiceProvider — enregistre les liaisons et publie la configuration.
  • NextPDF\Laravel\Facades\Pdf — un proxy statique qui récupère un document neuf depuis le conteneur.
  • NextPDF\Laravel\Http\PdfResponse — une fabrique de réponses PDF en ligne, en téléchargement et en flux, avec un jeu d’en-têtes de sécurité fixe.
  • NextPDF\Laravel\Jobs\GeneratePdfJob — un job pouvant être mis en file d’attente, qui construit et enregistre un PDF sur un worker.

Le fournisseur de services implémente DeferrableProvider, donc il n’enregistre ses liaisons que lorsque tu récupères l’une des entrées annoncées. Ce report allège le chemin de démarrage du framework. La méthode provides() du fournisseur liste les entrées différées, et le conteneur lit cette liste pour associer chaque clé à son fournisseur.

La résolution suit le contrat du conteneur : lorsqu’une liaison est présente, résoudre l’identifiant renvoie l’entrée enregistrée. PSR-11 est la PHP Standard Recommendation pour l’interopérabilité des conteneurs, et elle note que deux appels successifs à get() avec le même identifiant peuvent renvoyer des valeurs différentes, selon la stratégie de liaison (PSR-11 §1.1.2). NextPDF s’appuie volontairement sur ce comportement. Les registres sont des singletons, donc chaque résolution renvoie la même instance ; les documents sont liés via une fabrique, donc chaque résolution renvoie une instance neuve. Pour la table complète des durées de vie des liaisons, consulte /integrations/laravel/boot-and-discovery/.

L’architecture cible les workers à longue durée de vie, comme Octane, RoadRunner et Swoole. Le registre de polices est un singleton à durée de vie du processus : le package le préchauffe une fois puis le verrouille, donc aucune requête ne peut modifier l’état de police partagé. Le registre d’images est un singleton à durée de vie du processus, avec un cache borné selon la stratégie least-recently-used (LRU). Comme le package crée toujours un nouveau document à partir d’une DocumentFactory, l’état mutable propre à chaque requête ne fuit jamais d’une requête à l’autre.

ClassePoint d’entrée publicRenvoieRôle
NextPdfServiceProviderregister(), boot(), provides()void / arrayLiaisons de conteneur, publication de la configuration, liste des entrées différées
Facades\Pdfproxy statique (addPage(), cell(), save(), …)static / mixedRésout PdfDocumentInterface à chaque appel
Http\PdfResponseinline(), download(), streamInline(), streamDownload()Response / StreamedResponseRéponses HTTP avec en-têtes OWASP
Jobs\GeneratePdfJobdispatch(), handle(), then(), catch(), failed()PendingDispatch / void / selfGénération de PDF en file d’attente

Clés de conteneur liées par le fournisseur :

CléDurée de vieRésout vers
NextPDF\Contracts\FontRegistryInterface (alias FontRegistry)singleton, verrouilléNextPDF\Typography\FontRegistry
NextPDF\Graphics\ImageRegistrysingleton, borné par LRUImageRegistry
NextPDF\Contracts\DocumentFactoryInterface (alias DocumentFactory)singletonNextPDF\Core\DocumentFactory
Psr\Http\Client\ClientInterfacesingletonSecurityAwareHttpClient qui enveloppe CurlHttpClient
NextPDF\Security\Timestamp\TsaClientlimité à la portéeTsaClient ou null en l’absence d’URL TSA
NextPDF\Contracts\SignerInterfacefabriqueDigitalSigner ou null lorsque la signature est désactivée
NextPDF\Contracts\PdfDocumentInterface (alias nextpdf)fabriqueNextPDF\Core\Document
NextPDF\Contracts\EInvoice\{Embedder,Validator,Profile,SchematronRunner}Interfacefabriquene se résout que lorsque nextpdf/premium est installé
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'));

Pour un exemple exécutable au niveau d’un contrôleur, consulte /integrations/laravel/quickstart/.

Le pattern de production résout le contrat de document depuis le conteneur plutôt que depuis la façade, ce qui rend le point d’appel explicite et testable. Pour le contrôleur complet, avec injection de dépendances (DI) et gestion des erreurs, 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');
  • Le fournisseur est différé, donc résoudre une clé de conteneur sans rapport ne démarre pas NextPDF. Les liaisons n’apparaissent que lorsque tu demandes l’une des entrées de provides().
  • SignerInterface et TsaClient se résolvent en null par conception tant que tu n’as pas configuré la signature ou l’autorité d’horodatage. Ton code doit vérifier le résultat contre null ; ne suppose pas qu’une instance existe.
  • Les liaisons de contrat d’e-invoice sont toujours enregistrées, mais elles se résolvent en classes concrètes Premium qui n’existent que lorsque nextpdf/premium est installé. Les résoudre sans Premium lève une erreur de classe introuvable, et l’erreur apparaît à la première résolution, pas au démarrage.
  • La façade renvoie un document neuf à chaque résolution. Considère deux appels statiques Pdf:: dans la même requête, séparés par Pdf::clearResolvedInstances() : les deux appels opèrent sur des documents différents.

L’enregistrement du fournisseur s’exécute en temps O(1). Le fournisseur lie des closures et ne construit pas d’objets lourds, donc le coût de construction est reporté à la première résolution. Le préchauffage du registre de polices s’exécute en temps O(f), où f est le nombre de fichiers de polices préchargés, et il s’exécute une fois par processus worker. Ce séquencement amortit la latence de la première requête dans les workers à longue durée de vie. Le budget mémoire par page de cette vue d’ensemble est consigné dans le champ de front-matter performance_budget.

PdfResponse applique un jeu d’en-têtes fixe issu de l’Open Worldwide Application Security Project (OWASP). Les en-têtes sont X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Content-Security-Policy: default-src 'none', X-Robots-Tag et Referrer-Policy: no-referrer. GeneratePdfJob valide son chemin de sortie côté worker, et cette vérification atténue les charges utiles sérialisées altérées. Pour le modèle de menace complet et la configuration de déploiement, consulte /integrations/laravel/security-and-operations/.

AffirmationSourceClausereference_id
Résolution du conteneur / sémantique de durée de vieConteneur PSR-11§1.1.2
Mappage du préfixe d’autoload PSR-4Autoloader PSR-4§3

Lorsque nextpdf/premium est installé, le même fournisseur expose davantage de capacités : la signature numérique (PAdES B-B), l’archivage PDF/A et les liaisons de contrat d’e-invoice. Le fournisseur les expose via les mêmes clés de conteneur, donc le package Core documenté ici n’a besoin d’aucune modification de code pour adopter ces capacités. Pour plus de détails, consulte https://nextpdf.dev/get-license/?intent=laravel-signing.

  • /integrations/laravel/install/ — procédure d’installation et extensions optionnelles
  • /integrations/laravel/quickstart/ — exemple de contrôleur exécutable
  • /integrations/laravel/configuration/ — chaque clé de configuration, vérifiée par rapport à config/nextpdf.php
  • /integrations/laravel/production-usage/ — contrôleur câblé en DI, gestion des erreurs, mise en file d’attente
  • /integrations/laravel/boot-and-discovery/ — découverte automatique et durées de vie des liaisons
  • /integrations/laravel/security-and-operations/ — modèle de menace et configuration de déploiement