Salta ai contenuti

Risoluzione dei problemi del pacchetto Laravel NextPDF

Questa pagina riconduce ogni modalità di errore osservabile del pacchetto alla relativa causa radice verificata nel codice sorgente. Ogni voce riporta sintomo, causa e soluzione.

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

La maggior parte dei problemi segnalati rientra in cinque gruppi: discovery, risoluzione del container, firma, job in coda e nomi file HTTP. Per scelta progettuale, il pacchetto segnala gli errori in modo esplicito. Le funzionalità opzionali non configurate restituiscono null e gli input non sicuri generano eccezioni tipizzate. Di conseguenza, il sintomo indica solitamente in modo diretto la causa.

SintomoCausa verificataSoluzione
Provider non registrato dopo l’installazioneL’applicazione ha disattivato la discovery tramite extra.laravel.dont-discoverRimuovere il pacchetto da dont-discover oppure registrare NextPdfServiceProvider manualmente in bootstrap/providers.php
config('nextpdf') è vuotoConfigurazione non unita perché nessun binding dichiarato è stato risolto (provider deferred)Risolvere una qualsiasi voce di provides() oppure verificare la discovery con php artisan package:discover --ansi
config/nextpdf.php non creato dalla pubblicazioneTag di pubblicazione non corrispondenteUsare esattamente questo tag: php artisan vendor:publish --tag=nextpdf-config
RuntimeException: “NextPDF requires the ext-mbstring/ext-zlib PHP extension”Un’estensione PHP richiesta è assente in fase di runtimeInstallare o abilitare mbstring e zlib in php.ini
SintomoCausa verificataSoluzione
app(SignerInterface::class) restituisce nullFirma disabilitata o certificato vuoto in nextpdf.signatureImpostare signature.enabled = true e un signature.certificate valido; installare nextpdf/premium per la classe concreta del signer
app(TsaClient::class) restituisce nullnextpdf.tsa.url è vuotoConfigurare tsa.url (e credentials/pins secondo necessità)
Class-not-found per un tipo di versione PDF/Anextpdf.pdfa non è null ma nextpdf/premium non è installatoInstallare nextpdf/premium oppure reimpostare pdfa su null
Class-not-found durante la risoluzione di un contract per la fatturazione elettronicaI binding sono registrati, ma le classi concrete Premium sono assentiInstallare nextpdf/premium; i contract per la fatturazione elettronica vengono risolti in modo lazy e generano un errore solo alla prima risoluzione in assenza di Premium
Lo stesso documento viene modificato in due operazioni logiche distinteIl binding del documento è una factory; è stata riutilizzata un’unica istanza già risoltaRisolvere un nuovo PdfDocumentInterface per ogni documento

Quando il container non contiene la voce, get() genera un’eccezione not-found (PSR-11 §1.1.2). I contract per la fatturazione elettronica sono associati, quindi il metodo has() del container restituisce true. L’errore emerge dalla classe concreta Premium mancante durante la costruzione, non dal container stesso.

SintomoCausa verificataSoluzione
InvalidArgumentException: Path traversal sequences are not allowedIl percorso di output contiene un .. come segmentoUsare un percorso assoluto, privo di traversal, all’interno della directory di storage
InvalidArgumentException: Stream wrappers are not allowedIl percorso corrisponde a uno schema come php://Usare un semplice percorso di filesystem
InvalidArgumentException: Output path contains null bytesIl percorso contiene un byte \0Sanificare il percorso prima del dispatch
InvalidArgumentException: Output path must end with .pdf extensionIl percorso non termina con .pdf (senza distinzione tra maiuscole e minuscole)Usare un suffisso .pdf (o .PDF)
Il job viene eseguito ma il file è vuoto o erratoLa closure del builder non ha restituito il documento configuratoRestituire il documento dal builder; il valore restituito è ciò che viene salvato
Il job usa la coda o il timeout erratinextpdf.queue.* non è impostato come previstoImpostare queue.queue, queue.connection, queue.timeout; tries e backoff richiedono il subclassing

I controlli sul percorso vengono eseguiti dentro handle() sul worker, quindi un percorso errato fallisce in fase di esecuzione, non al dispatch. Si tratta di una scelta intenzionale: il payload serializzato sul transport della coda viene convalidato nel punto in cui viene consumato.

SintomoCausa verificataSoluzione
Il nome file del download risulta document.pdf in modo inattesoÈ stato passato un nome file vuoto; la factory applica il valore predefinitoPassare un nome file non vuoto
Il nome file non contiene più il percorso o i caratteri specialiIl sanitizer del nome file rimuove i separatori di percorso, i caratteri di controllo e i byte nullPassare solo il nome file di base; si tratta di una misura di hardening prevista
Il nome file non ASCII mostra mojibake in alcuni clientPer i nomi non ASCII viene emesso RFC 5987 filename*=; i client meno recenti leggono il fallback ASCIIComportamento previsto; fornire un nome ASCII-safe se serve una corrispondenza esatta su un client legacy
La risposta in streaming non ha Content-LengthLe risposte in streaming omettono Content-Length per scelta progettuale (output chunked)Comportamento previsto; usare inline()/download() non in streaming se è richiesto un header di lunghezza
Terminal window
# Confirm the provider is discovered
php artisan package:discover --ansi
# Inspect merged configuration
php artisan tinker --execute="dump(config('nextpdf.queue'));"
resource: src/Laravel/NextPdfServiceProvider.php (null-check pattern)
<?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.
}
  • Il provider deferred fa sì che una nuova installazione possa apparire «non funzionante» fino alla prima risoluzione pertinente. Il segnale corretto di esito positivo è la presenza del pacchetto nell’elenco di package:discover.
  • image_cache_mb = null ricade su 50 MB; solo 0 disabilita la cache. Una segnalazione di «cache non disabilitata» di solito deriva dall’uso di null.
  • signature.level = null ricade silenziosamente su PAdES B-B. Una segnalazione di «B-B inatteso» di solito deriva da un livello lasciato non impostato.

Se le prime richieste su un worker a lunga durata sono lente, il registro dei font sta eseguendo il parsing su richiesta. Valorizzare nextpdf.preload_fonts in modo che il warmup venga eseguito una sola volta all’avvio del worker. Per i dettagli, vedere /integrations/laravel/configuration/ e /integrations/laravel/boot-and-discovery/.

Il rifiuto di percorsi e nomi file è un controllo di sicurezza, non un bug. Non aggirarlo pre-decodificando o allentando i controlli. Instradare invece l’output dei file attraverso un percorso di storage controllato. Vedere /integrations/laravel/security-and-operations/.

AsserzioneFonteClausolareference_id
Una voce mancante nel container genera not-found su get()PSR-11 Container§1.1.2
  • /integrations/laravel/install/ — procedura di discovery e pubblicazione
  • /integrations/laravel/configuration/ — ogni chiave e il relativo valore predefinito
  • /integrations/laravel/production-usage/ — pattern di DI e coda
  • /integrations/laravel/security-and-operations/ — perché esistono i controlli sui percorsi