Aller au contenu

Guide du développeur Laravel

Le package Laravel adapte NextPDF aux conventions de Laravel sans modifier le cycle de vie du document du cœur. Le conteneur détient les registres et les fabriques partagés. Chaque document PDF est à usage unique et doit être construit, retourné, diffusé ou enregistré une seule fois.

Utilise ce guide lorsque tu conçois des services applicatifs, des jobs de file d’attente, des flux de réponse ou la couverture de tests autour de nextpdf/laravel.

CoucheDétenu parResponsabilitéÀ ne pas mettre ici
ContrôleurApplicationAutoriser la requête, choisir un constructeur de document et retourner une réponse.Les règles de mise en page PDF communes aux cas d’usage.
Service applicatifApplicationCollecter les données du domaine et appeler le code de construction du document.La logique d’amorçage du conteneur ou la configuration du package.
Constructeur de documentApplicationTraduire les données du domaine en appels de document NextPDF.Les objets de requête, la logique de requête Eloquent ou les détails du transport de file d’attente.
Intégration Laravelnextpdf/laravelLier les fabriques, les registres, le signataire, le client TSA, la façade, les réponses et le job de file d’attente.Les chemins de stockage propres au métier ou la politique de tenant.
Moteur du cœurnextpdf/nextpdfConstruire et sérialiser le PDF.La réponse Laravel, la file d’attente ou la politique du système de fichiers.
ÉtapeComportementAction du développeur
Enregistrement du service providerNextPdfServiceProvider::register() enregistre les registres partagés, la fabrique de documents, la liaison du document, le client HTTP, le client TSA, le signataire et les contrats e-invoice optionnels.Publie config/nextpdf.php et passe-le en revue avant la production.
Résolution du documentLa façade Pdf et la liaison PdfDocumentInterface résolvent un document neuf via DocumentFactoryInterface.Résous un document une seule fois par requête, commande ou job mis en file d’attente.
RédactionLe code applicatif appelle les API de document du cœur via la façade ou le document injecté.Garde l’extraction des données du domaine hors du constructeur de document.
Sortie terminalePdfResponse émet la sortie HTTP, ou le document est enregistré sur le disque.Choisis un seul chemin de sortie terminale pour chaque document.
Exécution en file d’attenteGeneratePdfJob reconstruit le document dans le worker et valide à nouveau le chemin de sortie.Passe un contexte scalaire et garde les callbacks idempotents.
CheminObjectif
app/Pdf/Builders/*Des constructeurs de documents purs. Ils reçoivent des données et retournent un document terminé.
app/Pdf/Data/*De petits DTO qui transportent une entrée de document déjà autorisée.
app/Services/*L’orchestration applicative, les requêtes, le relais d’autorisation et la sélection du chemin de stockage.
app/Jobs/*Des wrappers optionnels autour de GeneratePdfJob lorsque l’application a besoin de jobs nommés.
tests/Feature/Pdf/*Les tests de réponse HTTP, de dispatch en file d’attente et d’autorisation.
tests/Unit/Pdf/*Les tests de constructeur avec une entrée courte et déterministe.

Garde les constructeurs indépendants des objets de requête Laravel. Un constructeur doit pouvoir être appelé depuis un contrôleur, une commande, un test et un worker de file d’attente avec la même entrée.

<?php
namespace App\Pdf\Builders;
use App\Pdf\Data\InvoicePdfData;
use NextPDF\Contracts\PdfDocumentInterface;
final readonly class InvoicePdfBuilder
{
public function build(PdfDocumentInterface $pdf, InvoicePdfData $data): PdfDocumentInterface
{
$pdf->setTitle($data->title)
->addPage()
->setFont('dejavusans', '', 12)
->writeHtml($data->html);
return $pdf;
}
}

Utilise l’injection par constructeur lorsque le flux PDF fait partie de la logique applicative. N’utilise la façade que pour les flux de contrôleur courts où le style statique améliore la lisibilité.

<?php
namespace App\Http\Controllers;
use App\Pdf\Builders\InvoicePdfBuilder;
use App\Pdf\Data\InvoicePdfData;
use NextPDF\Contracts\PdfDocumentInterface;
use NextPDF\Laravel\Http\PdfResponse;
final readonly class DownloadInvoiceController
{
public function __invoke(
PdfDocumentInterface $pdf,
InvoicePdfBuilder $builder,
) {
$document = $builder->build(
$pdf,
InvoicePdfData::fromInvoiceId(1234),
);
return PdfResponse::download($document, 'invoice-1234.pdf');
}
}

Les helpers de réponse matérialisent les octets du document avant de construire la réponse Laravel. Ce sont des helpers de réponse, pas des moteurs de rendu d’arrière-plan.

GeneratePdfJob accepte un callable de construction et un chemin de sortie. Le job valide les chemins dangereux au moment de l’exécution. Le code applicatif doit malgré tout choisir une racine de stockage sûre pour le tenant avant le dispatch.

<?php
use App\Pdf\Builders\QueuedInvoiceBuilder;
use NextPDF\Laravel\Jobs\GeneratePdfJob;
GeneratePdfJob::dispatch(
outputPath: storage_path('app/pdfs/invoice-1234.pdf'),
builder: [QueuedInvoiceBuilder::class, 'build'],
)->onQueue(config('nextpdf.queue.queue', 'pdf'));

Les callbacks de file d’attente doivent rester courts. Préfère écrire un état durable depuis un listener de job applicatif plutôt que de stocker des closures complexes dans la charge utile de la file d’attente.

Point d’extensionÀ utiliser pourContrainte
PdfDocumentInterface (liaison)Remplacer ou décorer la création du document pour des valeurs par défaut à l’échelle de l’application.Doit retourner une instance de document neuve.
DocumentFactoryInterfaceCréer explicitement un document neuf dans les services et les tests.Ne mets pas en cache les documents retournés.
config/nextpdf.phpLes valeurs par défaut, les réglages de file d’attente, les réglages du moteur de rendu Chrome, les hooks de signature, le cache TSA et OCSP.Traite les variables d’environnement comme de la configuration de déploiement, pas comme une entrée de requête.
GeneratePdfJob (constructeur)Construire des documents de façon asynchrone.Le callable doit être sérialisable par le transport de file d’attente Laravel.
Les callbacks de succès et d’échecLa notification ou le nettoyage après génération.Garde les callbacks idempotents et maîtrise leurs effets de bord.
Les contrats Premium optionnelsL’intégrateur d’e-invoice, le validateur, le profil et l’exécuteur Schematron.Ne les résous que là où le package optionnel est installé et licencié.
  1. Construis le premier document de façon synchrone dans un contrôleur ou un test fonctionnel.
  2. Déplace le code de mise en page dans une classe de constructeur sous app/Pdf/Builders.
  3. Déplace la logique de requête et d’autorisation dans un service applicatif.
  4. Ajoute des tests PdfResponse pour les en-têtes et les noms de fichiers.
  5. Déplace la génération lente ou à fort volume vers GeneratePdfJob.
  6. Ajoute des tests de file d’attente pour le contexte sérialisé, la politique de chemin de sortie et la gestion des échecs.
  7. Mesure la mémoire et le temps de rendu avec des données de production représentatives.
ÉchecOù il doit être traitéRéponse recommandée
Requête invalide ou document non autoriséContrôleur ou politique.Retourne la réponse d’autorisation ou de validation applicative habituelle.
Police manquante ou image invalideTest de constructeur et journalisation applicative.Fais échouer la requête ou le job ; n’émets pas de PDF partiels.
Chemin de sortie dangereuxLe service de stockage applicatif et GeneratePdfJob.Rejette avant le dispatch et appuie-toi sur la validation côté worker comme défense en profondeur.
Échec de signature ou de TSALa frontière du service de signature.Décide si le document peut rester non signé ; par défaut, échoue en mode fermé pour les documents réglementés.
Délai d’attente de la file d’attente dépasséLa configuration et l’observabilité du worker de file d’attente.Ne réessaie que lorsque le constructeur est déterministe et que le chemin de sortie peut être écrasé sans risque.
PréoccupationValeur par défautQuand la remplacer
Nom de la file d’attentepdfUtilise une file d’attente dédiée quand la génération entre en concurrence avec les jobs destinés aux utilisateurs.
Délai d’attente du job120 secondesNe l’augmente qu’après avoir mesuré la taille du document et la capacité du worker.
Nom de fichier de la réponsedocument.pdfUtilise des identifiants métier assainis.
Registre de policesPartagé et verrouillé après le préchauffage.Ajoute preload_fonts pour les polices utilisées sur les chemins critiques.
Registre d’imagesCache partagé borné.Abaisse image_cache_mb pour les workers à mémoire limitée.
Découpage de la réponse diffusée en chunksChunks de 64 Ko.Ne dépends pas des frontières de chunk ; ce sont un détail de sortie.
  • Les tests de contrôleur vérifient Content-Type, Content-Disposition et les en-têtes défensifs.
  • Les tests de constructeur utilisent des DTO déterministes et n’interrogent pas la base de données.
  • Les tests de file d’attente vérifient que le constructeur reçoit un document neuf.
  • Les tests de chemin couvrent la traversée, le wrapper de flux, l’octet nul et le rejet des fichiers non-.pdf.
  • Les tests de worker rendent des documents représentatifs sous la même limite de mémoire qu’en production.
  • Les tests de signature optionnels couvrent le certificat manquant, le mot de passe invalide, le TSA indisponible et le niveau de signature configuré.