Dépannage du package Laravel NextPDF
Cette page associe chaque mode de défaillance observable du package à sa cause racine vérifiée dans le code source. Chaque entrée précise le symptôme, la cause et le correctif.
Installation
Section intitulée « Installation »composer require nextpdf/laravelphp artisan vendor:publish --tag=nextpdf-configVue d’ensemble conceptuelle
Section intitulée « Vue d’ensemble conceptuelle »La plupart des problèmes signalés relèvent de cinq catégories : découverte, résolution du conteneur, signature, jobs de file d’attente et noms de fichiers HTTP. Par conception, le package échoue de manière explicite. Les fonctionnalités optionnelles non configurées renvoient null, et une entrée non sûre lève des exceptions typées. Le symptôme indique donc généralement la cause directement.
Surface d’API — du symptôme à la cause
Section intitulée « Surface d’API — du symptôme à la cause »Découverte et amorçage
Section intitulée « Découverte et amorçage »| Symptôme | Cause vérifiée | Correctif |
|---|---|---|
| Le provider n’est pas enregistré après l’installation | L’application a désactivé la découverte via extra.laravel.dont-discover | Retire le package de dont-discover ou enregistre NextPdfServiceProvider manuellement dans bootstrap/providers.php |
config('nextpdf') est vide | La configuration n’a pas été fusionnée, car aucune liaison annoncée n’a été résolue (provider différé) | Résous n’importe quelle entrée provides() ou confirme la découverte avec php artisan package:discover --ansi |
config/nextpdf.php n’a pas été créé par la publication | Le tag de publication ne correspond pas | Utilise le tag exact : php artisan vendor:publish --tag=nextpdf-config |
| RuntimeException : « NextPDF requires the ext-mbstring/ext-zlib PHP extension » | Une extension PHP requise manque à l’exécution | Installe ou active mbstring et zlib dans php.ini |
Résolution du conteneur
Section intitulée « Résolution du conteneur »| Symptôme | Cause vérifiée | Correctif |
|---|---|---|
app(SignerInterface::class) renvoie null | La signature est désactivée, ou le certificat est vide dans nextpdf.signature | Définis signature.enabled = true et un signature.certificate valide ; installe nextpdf/premium pour le signataire concret |
app(TsaClient::class) renvoie null | nextpdf.tsa.url est vide | Configure tsa.url (et les credentials/pins si nécessaire) |
| Classe introuvable pour un type de version PDF/A | nextpdf.pdfa est non-null mais nextpdf/premium n’est pas installé | Installe nextpdf/premium, ou redéfinis pdfa à null |
| Classe introuvable lors de la résolution d’un contrat de facture électronique | Les liaisons sont enregistrées, mais les classes concrètes Premium sont absentes | Installe nextpdf/premium ; les contrats de facture électronique se résolvent paresseusement et n’échouent qu’à la première résolution sans Premium |
| Le même document est muté entre deux opérations logiques | La liaison du document est une factory ; tu as réutilisé une seule instance résolue | Résous une nouvelle instance de PdfDocumentInterface par document |
Quand une entrée est absente, le conteneur lève une exception « not-found » sur get() (PSR-11 §1.1.2). Les contrats de facture électronique sont liés ; le has() du conteneur renvoie donc vrai. L’erreur vient de la classe concrète Premium manquante au moment de la construction, et non du conteneur lui-même.
Jobs de file d’attente
Section intitulée « Jobs de file d’attente »| Symptôme | Cause vérifiée | Correctif |
|---|---|---|
InvalidArgumentException: Path traversal sequences are not allowed | Le chemin de sortie contient un segment de remontée .. | Utilise un chemin absolu, sans traversée, sous ton répertoire de stockage |
InvalidArgumentException: Stream wrappers are not allowed | Le chemin correspond à un schéma comme php:// | Utilise un simple chemin du système de fichiers |
InvalidArgumentException: Output path contains null bytes | Le chemin contient un octet nul \0 | Nettoie le chemin avant la mise en file d’attente |
InvalidArgumentException: Output path must end with .pdf extension | Le chemin ne se termine pas par .pdf (insensible à la casse) | Utilise un suffixe .pdf (ou .PDF) |
| Le job s’exécute, mais le fichier est vide ou incorrect | La closure du builder n’a pas renvoyé le document configuré | Renvoie le document depuis le builder ; la valeur renvoyée est celle qui est enregistrée |
| Le job utilise la mauvaise file d’attente ou le mauvais délai d’expiration | nextpdf.queue.* n’est pas défini comme attendu | Définis queue.queue, queue.connection, queue.timeout ; tries et backoff nécessitent de créer une sous-classe |
Les vérifications de chemin s’exécutent dans handle() sur le worker : un chemin incorrect échoue donc à l’exécution, et non à la mise en file d’attente. C’est intentionnel : la charge utile sérialisée dans le transport de file d’attente est validée là où elle est consommée.
Réponses HTTP et noms de fichiers
Section intitulée « Réponses HTTP et noms de fichiers »| Symptôme | Cause vérifiée | Correctif |
|---|---|---|
Le nom de fichier de téléchargement est document.pdf de façon inattendue | Un nom de fichier vide a été passé ; la factory lui applique sa valeur par défaut | Passe un nom de fichier non vide |
| Le nom de fichier a perdu son chemin ou ses caractères spéciaux | L’assainisseur de nom de fichier supprime les séparateurs de chemin, les caractères de contrôle et les octets nuls | Passe uniquement le nom de fichier de base ; c’est un durcissement attendu |
| Un nom de fichier non-ASCII affiche du mojibake sur certains clients | Le paramètre RFC 5987 filename*= est émis pour les noms non-ASCII ; les anciens clients lisent le repli ASCII | Attendu ; fournis un nom compatible ASCII si un client hérité doit afficher exactement le même nom |
La réponse en flux n’a pas de Content-Length | Les réponses en flux omettent Content-Length par conception (sortie en chunks) | Attendu ; utilise les méthodes non diffusées inline()/download() si un en-tête de longueur est requis |
Exemple de code — diagnostics
Section intitulée « Exemple de code — diagnostics »# Confirm the provider is discoveredphp artisan package:discover --ansi
# Inspect merged configurationphp artisan tinker --execute="dump(config('nextpdf.queue'));"<?php
declare(strict_types=1);
use NextPDF\Contracts\SignerInterface;
$signer = app(SignerInterface::class);
if ($signer === null) { // Signing not configured, or nextpdf/premium not installed. // Continue without a signature, or fail with a clear message.}Cas limites et pièges
Section intitulée « Cas limites et pièges »- Le provider différé signifie qu’une nouvelle installation peut sembler « cassée » jusqu’à la première résolution pertinente. Le bon signal de réussite est que
package:discoverliste le package. image_cache_mb = nullrevient à 50 Mo ; seul0désactive le cache. Un signalement « le cache ne se désactive pas » utilisait généralementnull.signature.level = nullrevient silencieusement à PAdES B-B. Un signalement « B-B inattendu » a généralement laissé le niveau non défini.
Performances
Section intitulée « Performances »Si les premières requêtes sur un worker à longue durée de vie sont lentes, le registre de polices analyse les polices à la demande. Renseigne nextpdf.preload_fonts pour que le préchauffage s’exécute une seule fois au démarrage du worker. Voir /integrations/laravel/configuration/ et /integrations/laravel/boot-and-discovery/ pour les détails.
Notes de sécurité
Section intitulée « Notes de sécurité »Les rejets liés aux chemins et aux noms de fichiers sont des contrôles de sécurité, pas des bugs. Ne les contourne pas en pré-décodant ni en assouplissant les vérifications. Achemine plutôt la sortie de fichier via un chemin de stockage contrôlé. Voir /integrations/laravel/security-and-operations/.
Conformité
Section intitulée « Conformité »| Affirmation | Source | Article | reference_id |
|---|---|---|---|
| Une entrée de conteneur manquante lève une erreur « not-found » sur get() | Conteneur PSR-11 | §1.1.2 |
Voir aussi
Section intitulée « Voir aussi »- /integrations/laravel/install/ — étapes de découverte et de publication
- /integrations/laravel/configuration/ — chaque clé et sa valeur par défaut
- /integrations/laravel/production-usage/ — modèles d’injection de dépendances et de file d’attente
- /integrations/laravel/security-and-operations/ — pourquoi les vérifications de chemin existent