Zum Inhalt springen

NextPDF-Laravel-Integration im Überblick

Das nextpdf/laravel-Paket verbindet die NextPDF-PDF-Engine mit einer Laravel-12-Anwendung und registriert die Container-Bindings. Es stellt eine Pdf-Facade, einen PdfResponse-HTTP-Helfer und einen GeneratePdfJob für die Queue bereit. Laravel erkennt das Paket automatisch, sodass Sie es nicht manuell registrieren müssen.

Terminal-Fenster
composer require nextpdf/laravel

Die Composer-Beschränkung lautet nextpdf/core: ^3.0 || ^5.2. Das Paket benötigt außerdem laravel/framework: ^12.0 und php: >=8.4 <9.0. Die vollständige Anleitung, einschließlich der Veröffentlichung der Konfiguration und optionaler Erweiterungen, finden Sie unter /integrations/laravel/install/.

Das Paket bildet eine schlanke Verbindungsschicht zwischen dem Laravel-Service-Container und dem frameworkunabhängigen NextPDF-Core. Es implementiert die PDF-Generierung nicht neu. Stattdessen bindet es das Core-Modell NextPDF\Core\Document in Laravels Lebenszyklus sowie in dessen Konfigurations-, Queueing- und HTTP-Schichten ein.

Das folgende Diagramm zeigt, wie eine Anfrage von Ihrem Anwendungscode durch das Paket bis in die gemeinsam genutzten Core-Registries fließt.

NextPDF Laravel request and render flowA request resolves a fresh document from the container, which the package adapts onto the shared font and image registries before HTTP or queue output.

Your Laravel app

Pdf facade

Laravel service container

NextPdfServiceProvider (deferred)

DocumentFactory (singleton)

Document (fresh per resolve)

FontRegistry (singleton, locked)

ImageRegistry (singleton, LRU)

PdfResponse (HTTP)

GeneratePdfJob (queue worker)

NextPDF Laravel request and render flow

Die Autoload-Map besteht aus einem einzigen PSR-4-Eintrag. PSR-4 ist die PHP Standard Recommendation für das Autoloading, und das Präfix NextPDF\Laravel\ wird auf src/Laravel/ abgebildet. Nach PSR-4 entspricht ein Namespace-Präfix einem Basisverzeichnis; der verbleibende Klassenname wird anschließend auf einen Dateipfad unterhalb dieses Verzeichnisses abgebildet (PSR-4 §3). Unter diesem Präfix liegen vier Produktionsklassen:

  • NextPDF\Laravel\NextPdfServiceProvider — registriert die Bindings und veröffentlicht die Konfiguration.
  • NextPDF\Laravel\Facades\Pdf — ein statischer Proxy, der ein frisches Dokument aus dem Container auflöst.
  • NextPDF\Laravel\Http\PdfResponse — eine Factory für Inline-, Download- und gestreamte PDF-Antworten mit einem festen Satz an Sicherheitsheadern.
  • NextPDF\Laravel\Jobs\GeneratePdfJob — ein queuefähiger Job, der ein PDF auf einem Worker erzeugt und speichert.

Der Service-Provider implementiert DeferrableProvider, sodass er seine Bindings erst registriert, wenn Sie einen der deklarierten Einträge auflösen. Dieses verzögerte Laden hält den Bootpfad des Frameworks schlank. Die provides()-Methode des Providers listet die aufgeschobenen Einträge auf, und der Container liest diese Liste, um jeden Schlüssel wieder dem Provider zuzuordnen.

Die Auflösung folgt dem Containerkontrakt: Ist ein Binding vorhanden, liefert das Auflösen des Bezeichners den registrierten Eintrag. PSR-11 ist die PHP Standard Recommendation für die Containerinteroperabilität und hält fest, dass zwei aufeinanderfolgende get()-Aufrufe mit demselben Bezeichner je nach Bindingstrategie unterschiedliche Werte liefern können (PSR-11 §1.1.2). NextPDF verlässt sich bewusst auf dieses Verhalten. Registries sind Singletons, sodass jede Auflösung dieselbe Instanz liefert; Dokumente sind an eine Factory gebunden, sodass jede Auflösung eine frische Instanz liefert. Die vollständige Tabelle der Bindinglebensdauern finden Sie unter /integrations/laravel/boot-and-discovery/.

Die Architektur ist auf langlebige Worker wie Octane, RoadRunner und Swoole ausgelegt. Die Font-Registry ist ein Singleton mit Prozesslebensdauer: Das Paket wärmt sie einmal auf und sperrt sie anschließend, sodass keine Anfrage den gemeinsam genutzten Font-Status ändern kann. Die Image-Registry ist ein Singleton mit Prozesslebensdauer und einem begrenzten Cache nach dem Least-Recently-Used-Prinzip (LRU). Weil das Paket das Dokument immer frisch aus einer DocumentFactory erzeugt, gelangt veränderlicher Per-Request-Status nie über Anfragegrenzen hinweg.

KlasseÖffentlicher EinstiegspunktLiefertZweck
NextPdfServiceProviderregister(), boot(), provides()void / arrayContainer-Bindings, Veröffentlichung der Konfiguration, Liste der aufgeschobenen Einträge
Facades\Pdfstatischer Proxy (addPage(), cell(), save(), …)static / mixedLöst pro Aufruf PdfDocumentInterface auf
Http\PdfResponseinline(), download(), streamInline(), streamDownload()Response / StreamedResponseHTTP-Antworten mit OWASP-Headern
Jobs\GeneratePdfJobdispatch(), handle(), then(), catch(), failed()PendingDispatch / void / selfPDF-Generierung in der Queue

Vom Provider gebundene Containerschlüssel:

SchlüsselLebensdauerLöst auf zu
NextPDF\Contracts\FontRegistryInterface (Alias FontRegistry)Singleton, gesperrtNextPDF\Typography\FontRegistry
NextPDF\Graphics\ImageRegistrySingleton, LRU-begrenztImageRegistry
NextPDF\Contracts\DocumentFactoryInterface (Alias DocumentFactory)SingletonNextPDF\Core\DocumentFactory
Psr\Http\Client\ClientInterfaceSingletonSecurityAwareHttpClient umhüllt CurlHttpClient
NextPDF\Security\Timestamp\TsaClientscopedTsaClient oder null, wenn keine TSA-URL vorliegt
NextPDF\Contracts\SignerInterfaceFactoryDigitalSigner oder null, wenn das Signieren deaktiviert ist
NextPDF\Contracts\PdfDocumentInterface (Alias nextpdf)FactoryNextPDF\Core\Document
NextPDF\Contracts\EInvoice\{Embedder,Validator,Profile,SchematronRunner}InterfaceFactorylöst nur auf, wenn nextpdf/premium installiert ist
resource: README.md Quick Start (verified against src/Laravel/Facades/Pdf.php)
<?php
declare(strict_types=1);
use NextPDF\Laravel\Facades\Pdf;
Pdf::addPage();
Pdf::cell(0, 10, 'Hello from Laravel', newLine: true);
Pdf::save(storage_path('app/hello.pdf'));

Ein lauffähiges Controllerbeispiel finden Sie unter /integrations/laravel/quickstart/.

Das Produktionsmuster löst den Dokumentkontrakt aus dem Container statt aus der Facade auf; dadurch bleibt die Aufrufstelle explizit und testbar. Den vollständigen Controller mit Dependency Injection (DI) und Fehlerbehandlung finden Sie unter /integrations/laravel/production-usage/.

resource: src/Laravel/Http/PdfResponse.php (download factory)
<?php
declare(strict_types=1);
use NextPDF\Contracts\PdfDocumentInterface;
use NextPDF\Laravel\Http\PdfResponse;
$document = app(PdfDocumentInterface::class);
$document->addPage();
$document->cell(0, 10, 'Invoice', newLine: true);
return PdfResponse::download($document, 'invoice.pdf');
  • Der Provider ist aufgeschoben, sodass das Auflösen eines nicht verwandten Containerschlüssels NextPDF nicht bootet. Die Bindings erscheinen nur, wenn Sie einen der provides()-Einträge anfordern.
  • SignerInterface und TsaClient werden absichtlich zu null aufgelöst, wenn Sie das Signieren oder die Zeitstempelstelle nicht konfiguriert haben. Ihr Code muss das Ergebnis auf null prüfen; gehen Sie nicht davon aus, dass eine Instanz existiert.
  • Die E-Invoice-Kontrakt-Bindings sind immer registriert, werden aber zu Premium-Concretes aufgelöst, die nur existieren, wenn nextpdf/premium installiert ist. Wenn Sie sie ohne Premium auflösen, löst das einen Class-not-found-Fehler aus; der Fehler erscheint bei der ersten Auflösung, nicht beim Boot.
  • Die Facade liefert pro Auflösung ein frisches Dokument. Betrachten Sie zwei statische Pdf::-Aufrufe in derselben Anfrage, die durch Pdf::clearResolvedInstances() getrennt sind: Die beiden Aufrufe arbeiten auf verschiedenen Dokumenten.

Die Provider-Registrierung läuft in O(1)-Zeit. Der Provider bindet Closures und konstruiert keine schweren Objekte, sodass die Konstruktionskosten bis zur ersten Auflösung aufgeschoben werden. Das Aufwärmen der Font-Registry läuft in O(f)-Zeit, wobei f die Anzahl der vorgeladenen Fontdateien ist, und erfolgt einmal pro Worker-Prozess. Dieses Vorgehen amortisiert die Latenz der ersten Anfrage in langlebigen Workern. Das Per-Page-Speicherbudget für diesen Überblick ist im Frontmatter-Feld performance_budget festgehalten.

PdfResponse wendet einen festen Headersatz des Open Worldwide Application Security Project (OWASP) an. Die Header sind X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Content-Security-Policy: default-src 'none', X-Robots-Tag und Referrer-Policy: no-referrer. GeneratePdfJob validiert seinen Ausgabepfad auf der Worker-Seite, und diese Prüfung entschärft manipulierte serialisierte Payloads. Das vollständige Bedrohungsmodell und die Deployment-Konfiguration finden Sie unter /integrations/laravel/security-and-operations/.

BehauptungQuelleKlauselreference_id
Container-Auflösung / Lebensdauer-SemantikPSR-11 Container§1.1.2
PSR-4-Autoload-Präfix-AbbildungPSR-4 Autoloader§3

Wenn nextpdf/premium installiert ist, stellt derselbe Provider zusätzliche Funktionen bereit: digitales Signieren (PAdES B-B), PDF/A-Archivierung und E-Invoice-Kontrakt-Bindings. Der Provider stellt sie über dieselben Containerschlüssel bereit, sodass das hier dokumentierte Core-Paket keine Codeänderung benötigt, um diese Funktionen zu übernehmen. Details finden Sie unter https://nextpdf.dev/get-license/?intent=laravel-signing.

  • /integrations/laravel/install/ — Installationsanleitung und optionale Erweiterungen
  • /integrations/laravel/quickstart/ — lauffähiges Controllerbeispiel
  • /integrations/laravel/configuration/ — alle Konfigurationsschlüssel, verifiziert gegen config/nextpdf.php
  • /integrations/laravel/production-usage/ — Controller mit DI-Verdrahtung, Fehlerbehandlung, Queueing
  • /integrations/laravel/boot-and-discovery/ — Auto-Discovery und Lebensdauern der Bindings
  • /integrations/laravel/security-and-operations/ — Bedrohungsmodell und Deployment-Konfiguration