Fehlerbehebung beim NextPDF-Laravel-Paket
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Diese Seite ordnet jeden beobachtbaren Fehlermodus des Pakets seiner verifizierten Ursache im Quellcode zu. Jeder Eintrag nennt das Symptom, die Ursache und die Behebung.
Installation
Abschnitt betitelt „Installation“composer require nextpdf/laravelphp artisan vendor:publish --tag=nextpdf-configKonzeptioneller Überblick
Abschnitt betitelt „Konzeptioneller Überblick“Die meisten gemeldeten Probleme fallen in fünf Gruppen: Discovery, Container-Auflösung, Signierung, Queue-Jobs und HTTP-Dateinamen. Das Paket schlägt bewusst laut fehl. Nicht konfigurierte optionale Funktionen geben null zurück, und unsichere Eingaben lösen typisierte Exceptions aus. Dadurch verweist das Symptom in der Regel direkt auf die Ursache.
API-Oberfläche — vom Symptom zur Ursache
Abschnitt betitelt „API-Oberfläche — vom Symptom zur Ursache“Discovery und Boot
Abschnitt betitelt „Discovery und Boot“| Symptom | Bestätigte Ursache | Behebung |
|---|---|---|
| Provider nach der Installation nicht registriert | Die Anwendung meldet das Paket über extra.laravel.dont-discover von der Discovery ab | Entfernen Sie das Paket aus dont-discover oder registrieren Sie NextPdfServiceProvider manuell in bootstrap/providers.php |
config('nextpdf') ist leer | Die Konfiguration wurde nicht zusammengeführt, weil kein angekündigtes Binding aufgelöst wurde (deferred Provider) | Lösen Sie einen beliebigen provides()-Eintrag auf oder bestätigen Sie die Discovery mit php artisan package:discover --ansi |
config/nextpdf.php wurde beim Publish nicht erstellt | Falscher Publish-Tag | Verwenden Sie den exakten Tag: php artisan vendor:publish --tag=nextpdf-config |
| RuntimeException: „NextPDF requires the ext-mbstring/ext-zlib PHP extension“ | Eine benötigte PHP-Extension fehlt zur Laufzeit | Installieren oder aktivieren Sie mbstring und zlib in php.ini |
Container-Auflösung
Abschnitt betitelt „Container-Auflösung“| Symptom | Bestätigte Ursache | Behebung |
|---|---|---|
app(SignerInterface::class) liefert null | Die Signierung ist deaktiviert oder das Zertifikat in nextpdf.signature ist leer | Setzen Sie signature.enabled = true und ein gültiges signature.certificate; installieren Sie nextpdf/premium für die konkrete Signer-Implementierung |
app(TsaClient::class) liefert null | nextpdf.tsa.url ist leer | Konfigurieren Sie tsa.url (und bei Bedarf credentials/pins) |
| Class-not-found für einen PDF/A-Versionstyp | nextpdf.pdfa ist nicht null, aber nextpdf/premium ist nicht installiert | Installieren Sie nextpdf/premium oder setzen Sie pdfa zurück auf null |
| Class-not-found beim Auflösen eines E-Invoice-Vertrags | Die Bindings sind registriert, aber die konkreten Premium-Implementierungen fehlen | Installieren Sie nextpdf/premium; die E-Invoice-Verträge werden lazy aufgelöst und schlagen ohne Premium erst bei der ersten Auflösung fehl |
| Dasselbe Dokument wird über zwei logische Operationen hinweg mutiert | Das Dokument-Binding ist eine Factory; Sie haben eine bereits aufgelöste Instanz wiederverwendet | Lösen Sie pro Dokument ein frisches PdfDocumentInterface auf |
Fehlt ein Container-Eintrag, wirft get() eine Not-found-Exception (PSR-11 §1.1.2). Die E-Invoice-Verträge sind gebunden, daher ist has() des Containers true. Der Fehler entsteht durch die fehlende konkrete Premium-Implementierung zum Zeitpunkt der Konstruktion, nicht durch den Container selbst.
Queue-Jobs
Abschnitt betitelt „Queue-Jobs“| Symptom | Bestätigte Ursache | Behebung |
|---|---|---|
InvalidArgumentException: Path traversal sequences are not allowed | Der Ausgabepfad enthält ein ..-Segment | Verwenden Sie einen absoluten, traversierungsfreien Pfad unterhalb Ihres Storage-Verzeichnisses |
InvalidArgumentException: Stream wrappers are not allowed | Der Pfad entspricht einem Schema wie php:// | Verwenden Sie einen einfachen Dateisystempfad |
InvalidArgumentException: Output path contains null bytes | Der Pfad enthält ein \0-Byte | Bereinigen Sie den Pfad vor dem Dispatch |
InvalidArgumentException: Output path must end with .pdf extension | Der Pfad endet nicht auf .pdf (unabhängig von Groß-/Kleinschreibung) | Verwenden Sie eine .pdf- (oder .PDF-)Endung |
| Der Job läuft, aber die Datei ist leer oder falsch | Die Builder-Closure hat das konfigurierte Dokument nicht zurückgegeben | Geben Sie das Dokument aus dem Builder zurück; gespeichert wird der zurückgegebene Wert |
| Der Job verwendet die falsche Queue oder das falsche Timeout | nextpdf.queue.* ist nicht wie erwartet gesetzt | Setzen Sie queue.queue, queue.connection, queue.timeout; tries und backoff erfordern Subclassing |
Die Pfadprüfungen laufen innerhalb von handle() auf dem Worker; daher schlägt ein ungültiger Pfad bei der Ausführung fehl, nicht beim Dispatch. Das ist beabsichtigt: Die serialisierte Payload im Queue-Transport wird dort validiert, wo sie verarbeitet wird.
HTTP-Responses und Dateinamen
Abschnitt betitelt „HTTP-Responses und Dateinamen“| Symptom | Bestätigte Ursache | Behebung |
|---|---|---|
Der Download-Dateiname ist document.pdf – unerwartet | Es wurde ein leerer Dateiname übergeben; die Factory setzt einen Standardwert ein | Übergeben Sie einen nicht-leeren Dateinamen |
| Der Dateiname hat seinen Pfad oder Sonderzeichen verloren | Der Dateinamensanitizer entfernt Pfadtrenner, Steuerzeichen und Null-Bytes | Übergeben Sie nur den Basisdateinamen; dies ist die erwartete Härtung |
| Ein Nicht-ASCII-Dateiname wird in manchen Clients als Mojibake angezeigt | RFC 5987 filename*= wird für Nicht-ASCII-Namen ausgegeben; alte Clients lesen den ASCII-Fallback | Erwartet; geben Sie einen ASCII-sicheren Namen an, wenn ein Legacy-Client exakt übereinstimmen muss |
Eine gestreamte Response hat kein Content-Length | Gestreamte Responses lassen Content-Length bewusst weg (chunked Output) | Erwartet; verwenden Sie das nicht-gestreamte inline()/download(), wenn ein Längen-Header benötigt wird |
Codebeispiel — Diagnose
Abschnitt betitelt „Codebeispiel — Diagnose“# 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.}Sonderfälle & Stolperfallen
Abschnitt betitelt „Sonderfälle & Stolperfallen“- Der deferred Provider kann dazu führen, dass eine frische Installation „kaputt“ wirkt, bis die erste relevante Auflösung erfolgt. Das korrekte Erfolgssignal ist, dass
package:discoverdas Paket auflistet. image_cache_mb = nullfällt auf 50 MB zurück; nur0deaktiviert den Cache. Bei Meldungen wie „Cache deaktiviert sich nicht“ wurde meistnullverwendet.signature.level = nullfällt stillschweigend auf PAdES B-B zurück. Bei Meldungen wie „unerwartetes B-B“ war die Stufe meist nicht gesetzt.
Performance
Abschnitt betitelt „Performance“Wenn die ersten Requests auf einem langlebigen Worker langsam sind, wird die Font-Registry on demand geparst. Befüllen Sie nextpdf.preload_fonts, damit das Warmup beim Worker-Boot einmal ausgeführt wird. Siehe /integrations/laravel/configuration/ und /integrations/laravel/boot-and-discovery/ für Details.
Sicherheitshinweise
Abschnitt betitelt „Sicherheitshinweise“Die Ablehnungen von Pfaden und Dateinamen sind Sicherheitskontrollen, keine Bugs. Umgehen Sie sie nicht durch Vordekodierung oder durch aufgeweichte Prüfungen. Leiten Sie die Dateiausgabe stattdessen über einen kontrollierten Storage-Pfad. Siehe /integrations/laravel/security-and-operations/.
Konformität
Abschnitt betitelt „Konformität“| Behauptung | Quelle | Klausel | reference_id |
|---|---|---|---|
| Fehlender Container-Eintrag wirft bei get() eine Not-found-Exception | PSR-11 Container | §1.1.2 |
Siehe auch
Abschnitt betitelt „Siehe auch“- /integrations/laravel/install/ — Discovery- und Publish-Schritte
- /integrations/laravel/configuration/ — jeder Schlüssel und sein Standardwert
- /integrations/laravel/production-usage/ — DI- und Queue-Muster
- /integrations/laravel/security-and-operations/ — warum die Pfadprüfungen existieren