Zum Inhalt springen

Laravel-Entwicklerleitfaden

Das Laravel-Paket richtet NextPDF an den Laravel-Konventionen aus, ohne den zentralen Dokument-Lebenszyklus zu verändern. Der Container verwaltet die gemeinsam genutzten Registries und Factories. Jedes PDF-Dokument ist verwerfbar und sollte genau einmal erstellt, zurückgegeben, gestreamt oder gespeichert werden.

Verwenden Sie diesen Leitfaden, wenn Sie Anwendungsdienste, Queue-Jobs, Response-Abläufe oder die Testabdeckung rund um nextpdf/laravel entwerfen.

SchichtIm Besitz vonVerantwortungHier nicht ablegen
ControllerAnwendungAnfrage autorisieren, einen Dokument-Builder auswählen und eine Response zurückgeben.PDF-Layoutregeln, die über mehrere Anwendungsfälle hinweg gemeinsam genutzt werden.
AnwendungsdienstAnwendungDomänendaten sammeln und den Code zur Dokumenterstellung aufrufen.Container-Boot-Logik oder Paketkonfiguration.
Dokument-BuilderAnwendungDomänendaten in NextPDF-Dokumentaufrufe übersetzen.Request-Objekte, Eloquent-Query-Logik oder Details des Queue-Transports.
Laravel-Integrationnextpdf/laravelBindet Factories, Registries, Signer, TSA-Client, Facade, Responses und Queue-Job.Geschäftsspezifische Speicherpfade oder Mandantenrichtlinien.
Kern-Enginenextpdf/nextpdfBaut das PDF und serialisiert es.Laravel-Response-, Queue- oder Dateisystemrichtlinien.
PhaseVerhaltenEntwickleraktion
Registrierung des Service-ProvidersNextPdfServiceProvider::register() registriert die gemeinsam genutzten Registries, die Dokument-Factory, das Dokument-Binding, den HTTP-Client, den TSA-Client, den Signer und die optionalen E-Invoice-Contracts.Veröffentlichen Sie config/nextpdf.php und prüfen Sie die Datei vor dem Produktivbetrieb.
DokumentauflösungDie Pdf-Facade und das PdfDocumentInterface-Binding lösen ein frisches Dokument über DocumentFactoryInterface auf.Lösen Sie ein Dokument einmal pro Anfrage, Command oder Queue-Job auf.
ErstellungDer Anwendungscode ruft die zentralen Dokument-APIs über die Facade oder das injizierte Dokument auf.Halten Sie die Extraktion der Domänendaten außerhalb des Dokument-Builders.
EndausgabePdfResponse gibt die HTTP-Ausgabe aus, oder das Dokument wird auf die Festplatte gespeichert.Wählen Sie pro Dokument genau einen Pfad für die Endausgabe.
Queue-AusführungGeneratePdfJob baut das Dokument im Worker neu und validiert den Ausgabepfad erneut.Übergeben Sie skalaren Kontext und halten Sie Callbacks idempotent.
PfadZweck
app/Pdf/Builders/*Reine Dokument-Builder. Sie erhalten Daten und geben ein fertiges Dokument zurück.
app/Pdf/Data/*Kleine DTOs, die bereits autorisierte Dokumenteingaben transportieren.
app/Services/*Anwendungsorchestrierung, Queries, Weitergabe der Autorisierung und Auswahl des Speicherpfads.
app/Jobs/*Optionale Wrapper um GeneratePdfJob, wenn die Anwendung benannte Jobs benötigt.
tests/Feature/Pdf/*Tests für HTTP-Responses, Queue-Dispatch und Autorisierung.
tests/Unit/Pdf/*Builder-Tests mit kleinen, deterministischen Eingaben.

Halten Sie Builder unabhängig von Laravel-Request-Objekten. Ein Builder sollte mit derselben Eingabe aus einem Controller, einem Command, einem Test und einem Queue-Worker aufrufbar sein.

<?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;
}
}

Verwenden Sie Constructor-Injection, wenn der PDF-Ablauf Teil der Anwendungslogik ist. Verwenden Sie die Facade nur für kurze Controller-Abläufe, in denen der statische Stil die Lesbarkeit verbessert.

<?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');
}
}

Response-Helfer materialisieren die Dokument-Bytes, bevor die Laravel-Response erstellt wird. Sie sind Response-Helfer, keine Hintergrund-Renderer.

GeneratePdfJob akzeptiert ein Builder-Callable und einen Ausgabepfad. Der Job validiert unsichere Pfade zur Ausführungszeit. Der Anwendungscode sollte dennoch vor dem Dispatch ein mandantensicheres Speicher-Root auswählen.

<?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'));

Queue-Callbacks sollten klein bleiben. Schreiben Sie dauerhaften Zustand lieber aus einem Application-Job-Listener heraus, statt komplexe Closures in der Queue-Payload zu speichern.

ErweiterungspunktNutze es fürEinschränkung
PdfDocumentInterface-BindingErsetzen oder Dekorieren der Dokumenterstellung für anwendungsweite Standardwerte.Muss eine frische Dokumentinstanz zurückgeben.
DocumentFactoryInterfaceExplizites Erzeugen frischer Dokumente in Diensten und Tests.Zurückgegebene Dokumente nicht cachen.
config/nextpdf.phpStandardwerte, Queue-Einstellungen, Chrome-Renderer-Einstellungen, Signing-Hooks, TSA und OCSP-Cache.Behandeln Sie Umgebungsvariablen als Deployment-Konfiguration, nicht als Request-Eingabe.
GeneratePdfJob-BuilderDokumente asynchron bauen.Das Callable muss vom Queue-Transport von Laravel serialisierbar sein.
Erfolgs-/Fehler-CallbacksBenachrichtigungen oder Aufräumarbeiten nach der Generierung.Halten Sie Callbacks idempotent und berücksichtigen Sie Seiteneffekte.
Optionale Premium-ContractsE-Invoice-Embedder, Validator, Profil und Schematron-Runner.Lösen Sie sie nur dort auf, wo das optionale Paket installiert und lizenziert ist.
  1. Bauen Sie das erste Dokument synchron in einem Controller oder Feature-Test.
  2. Verschieben Sie den Layout-Code in eine Builder-Klasse unter app/Pdf/Builders.
  3. Verschieben Sie Query- und Autorisierungslogik in einen Anwendungsdienst.
  4. Fügen Sie PdfResponse-Tests für Header und Dateinamen hinzu.
  5. Verschieben Sie langsame oder hochvolumige Generierung nach GeneratePdfJob.
  6. Fügen Sie Queue-Tests für serialisierten Kontext, die Ausgabepfad-Richtlinie und die Fehlerbehandlung hinzu.
  7. Messen Sie Speicherverbrauch und Renderzeit mit repräsentativen Produktionsdaten.
FehlerWo er behandelt werden sollteEmpfohlene Reaktion
Ungültige Anfrage oder nicht autorisiertes DokumentController oder Policy.Geben Sie die normale Autorisierungs- oder Validierungs-Response der Anwendung zurück.
Fehlende Schrift oder ungültiges BildBuilder-Test und Anwendungs-Logging.Lassen Sie die Anfrage oder den Job fehlschlagen; geben Sie keine unvollständigen PDFs aus.
Unsicherer AusgabepfadSpeicherdienst der Anwendung und GeneratePdfJob.Lehnen Sie ihn vor dem Dispatch ab und verlassen Sie sich auf die Validierung auf Worker-Seite als Verteidigung in der Tiefe.
Signing- oder TSA-FehlerGrenze zum Signing-Dienst.Entscheiden Sie, ob das Dokument unsigniert sein darf; bei regulierten Dokumenten standardmäßig fail-closed.
Queue-TimeoutKonfiguration und Observability des Queue-Workers.Wiederholen Sie nur, wenn der Builder deterministisch ist und der Ausgabepfad sicher überschrieben werden darf.
AspektStandardwertWann überschreiben
Queue-NamepdfVerwenden Sie eine eigene Queue, wenn die Generierung mit nutzerseitigen Jobs konkurriert.
Job-Timeout120 SekundenErhöhen Sie ihn erst, nachdem Sie Dokumentgröße und Worker-Kapazität gemessen haben.
Response-Dateinamedocument.pdfVerwenden Sie bereinigte Geschäftskennungen.
Font-RegistryGemeinsam genutzt und nach dem Warmup gesperrt.Fügen Sie preload_fonts für Schriften hinzu, die auf heißen Pfaden genutzt werden.
Image-RegistryGemeinsam genutzter, begrenzter Cache.Senken Sie image_cache_mb für Worker mit knappem Speicher.
Chunking der gestreamten Response64-KB-Chunks.Verlassen Sie sich nicht auf Chunk-Grenzen; sie sind ein Ausgabedetail.
  • Controller-Tests prüfen Content-Type, Content-Disposition und defensive Header.
  • Builder-Tests verwenden deterministische DTOs und greifen nicht auf die Datenbank zu.
  • Queue-Tests prüfen, dass der Builder ein frisches Dokument erhält.
  • Pfad-Tests decken Traversal, Stream-Wrapper, Null-Bytes und die Ablehnung von Nicht-.pdf-Dateien ab.
  • Worker-Tests rendern repräsentative Dokumente unter demselben Speicherlimit wie in der Produktion.
  • Optionale Signing-Tests decken fehlendes Zertifikat, ungültiges Passwort, nicht verfügbare TSA und das konfigurierte Signaturniveau ab.