Zum Inhalt springen
getnextpdf.com

Eine Engine, jedes Framework

Spec: PSR-11 Container, §1.1.2Spec: PSR-4 Autoloader, §3

Die meisten wachsenden PHP-Landschaften enden mit mehr als einem Framework. NextPDF ist eine PDF-Engine, die jedem von ihnen zu seinen eigenen Bedingungen begegnet: idiomatische Bridges für Laravel, Symfony und CodeIgniter sowie ein Standalone-Pfad für Code, der in keinem von ihnen läuft. Das Dokumentmodell ist geteilt. Nur die Art, wie Sie es aufrufen, ändert sich.

Eine andere PDF-Bibliothek pro Stack ist eine stille Steuer. Jede hat ihre eigenen Eigenheiten, ihre eigene Schriftartenbehandlung, ihre eigene Vorstellung davon, was gültig bedeutet. Eine Rechnung, die vom Laravel-Service korrekt gerendert wird, kann vom Symfony-Worker subtil anders gerendert werden, weil eine andere Bibliothek sie gezeichnet hat. Nun hängen Ihr Archivierungsziel, Ihre Signaturplatzierung und Ihre Barrierefreiheits-Tags davon ab, welches Team das Dokument ausgeliefert hat. Im Fehlerbericht steht „das PDF ist falsch“, und die Antwort hängt davon ab, welche von drei Engines es erzeugt hat.

Die Standardisierung auf eine Engine lässt diese Fläche zusammenbrechen. Es gibt einen einzigen Ort, an dem ein PDF/A-Profil entschieden wird, eine Schriftarten-Pipeline zu zertifizieren, einen Validator, dem man vertraut. Das Framework, in dem Sie sich zufällig befinden, hört auf, eine Variable dafür zu sein, ob das Dokument korrekt ist.

  • Die Core-Engine ist framework-agnostisch. nextpdf/core weiß nichts über HTTP, Routing oder Container-Verdrahtung. Es ist eine PDF-2.0-Engine und nichts weiter.
  • Jede Bridge adaptiert, sie implementiert nicht neu. Die Pakete für Laravel, Symfony und CodeIgniter geben Ihnen eine Fassade oder Factory, einen HTTP-Response-Helfer und einen warteschlangenbasierten oder asynchronen Erzeugungspfad — über derselben Engine.
  • Eine Bridge folgt Ihrem Framework, nicht Ihrem Dokument. Sie ändert, wie Sie die Engine aufrufen, niemals das, was die Engine erzeugen kann.
  • Standalone ist immer verfügbar. Ein CLI-Werkzeug, ein Daemon oder eine Bibliothek hat kein Framework, von dem aus zu überbrücken wäre; sie konstruiert ein Dokument direkt.
  • Ein Dokumentmodell reist über alle vier hinweg. Dieselben Value Objects, Enums und derselbe Output-Vertrag tauchen überall auf, sodass sich ein Dokument unverändert zwischen Aufrufstellen bewegt.

Die Architektur ist eine bewusste Aufteilung. Die Engine ist der Wert; die Bridge ist ein dünner Adapter, der die Idiome eines Frameworks spricht. Eine Bridge registriert einen kleinen Namespace über dem geteilten Core durch Standard-Autoloading (Spec: PSR-4 Autoloader, §3) und gibt ein Dokument über den Container-Vertrag zurück (Spec: PSR-11 Container, §1.1.2). Dieser Vertrag ist der stille Held hier: Er erlaubt, dass zwei Auflösungen desselben Bezeichners unterschiedliche Instanzen zurückgeben, und genau so gibt Ihnen eine Bridge pro Anfrage ein frisches, wegwerfbares Dokument, während sie die geparste Schriftarten-Registry und den Bildcache als prozessweite Singletons behält. Langlebige Worker — Octane, RoadRunner, Swoole, Messenger — erhalten amortisiertes Schriftarten-Parsing ohne anfragenübergreifendes Zustandsleck, schon durch ihre Konstruktion.

Die vier Idiome unterscheiden sich nur an der Oberfläche:

  1. Core enginenextpdf/core — the framework-agnostic PDF 2.0 engine; the single shared document model, value objects, and output contract.
  2. Laravel bridgenextpdf/laravel — auto-discovered provider, a Pdf facade, a PdfResponse helper, and a queued GeneratePdfJob.
  3. Symfony bridgenextpdf/symfony — an auto-registered bundle, an injectable PdfFactory, a PdfResponse, and an optional Messenger handler.
  4. CodeIgniter bridgenextpdf/codeigniter — a service and pdf() helper, a Pdf library over a disposable Document, and a PdfResponse.
  5. StandaloneNo framework to bridge from — construct a Document directly in a CLI tool, daemon, or library.
Eine framework-agnostische Core-Engine, über vier idiomatische Oberflächen erreicht: eine Laravel-Fassade, eine injizierte Symfony-Factory, ein CodeIgniter-Service oder ein direkt konstruiertes Standalone-Dokument — jede gibt dasselbe wegwerfbare Document-Modell zurück.

Lesen Sie das Diagramm von links nach rechts, und die Lehre ist die Symmetrie. Jede Oberfläche löst sich zum selben Document auf. Die Laravel-Fassade, die Symfony-Factory, der CodeIgniter-Service und der Standalone-Konstruktor sind vier Türen in einen Raum.

Dieselben drei Zeilen Absicht, in jedem Idiom ausgedrückt. Der Rumpf, der das Dokument aufbaut — Seiten, Schriftarten, Zellen, Signieren, Konformität —, ist in allen vier identisch, weil es dieselbe Engine ist.

<?php
declare(strict_types=1);
// Laravel — resolve a fresh document from the container.
use NextPDF\Contracts\PdfDocumentInterface;
$document = app(PdfDocumentInterface::class);
// Symfony — inject the factory, then ask it for a document.
use NextPDF\Symfony\Service\PdfFactory;
$document = $factory->create(); // PdfFactory injected into your service
// CodeIgniter — pull it from the Services layer.
use NextPDF\CodeIgniter\Config\Services;
$document = Services::pdfDocument();
// Standalone — no framework; construct it directly.
use NextPDF\Core\Document;
$document = Document::createStandalone();
// From here, the code is identical regardless of how $document arrived.
$document->addPage();
$document->cell(0, 10, 'One engine, every framework', newLine: true);
$bytes = $document->getPdfData();

Die ersten Zeilen sind der einzige Unterschied. Alles danach ist portabel: Verschieben Sie einen dokumentaufbauenden Service von Symfony zu einem Standalone-Worker, und der Rendering-Code ändert sich nicht, weil sich der Vertrag, von dem er abhängt, nicht geändert hat.

Die häufige Annahme ist, dass die Framework-Bridge Fähigkeiten freischaltet — dass die Langzeit-Signaturvalidierung oder strukturiertes E-Invoicing eintritt, weil Sie nextpdf/laravel installiert haben, statt die Engine direkt aufzurufen. So ist es nicht. Eine Bridge ändert die Aufrufstelle, niemals die Reichweite der Engine. Core-Fähigkeiten wie PDF/A-Ausgabe und PAdES-Baseline-Signierung sind Open Source und erreichen jede Oberfläche; fortgeschrittene Fähigkeiten werden von einer Edition freigeschaltet und sind dann gleichermaßen über jede Bridge oder den Standalone-Pfad verfügbar. Eine Framework-Integration zu wählen, heißt nicht, einen Funktionsumfang zu wählen.

Das gespiegelte Missverständnis ist, dass „eine Engine“ einen einzigen Rendering-Pfad für jedes Dokument bedeuten müsse. Das tut es nicht. Die In-Process-Engine rendert PDF direkt; wenn ein Dokument tatsächlich eine Layout-Engine in Browser-Qualität benötigt, übernimmt das ein Renderer-Paket. Rendering und Aufruf sind getrennte Achsen — der Integrationsentscheidungsleitfaden ist der Ort, der sie zuordnet.

Eine Bridge erweitert nicht das, was die Engine rendern kann. Das ist die ehrliche Grenze, und sie ist der Punkt: Die Fähigkeit lebt im Core und in der Stufe, nicht im Adapter, über den Sie sie erreichen.

Framework bridges over one engine — edition availability
EditionAvailability
Core

Jede Bridge (Laravel, Symfony, CodeIgniter) und der Standalone-Pfad sind Apache-2.0 und arbeiten gegen Core. Sie adaptieren die Engine oder legen sie offen; sie gaten keine Funktionen und ändern nicht, was sie erzeugen kann.

Pro

Fortgeschrittene Fähigkeiten wie die Langzeit-Signaturvalidierung (PAdES B-LT und B-LTA) werden von einer Edition freigeschaltet und dann identisch über jede Bridge oder Standalone erreicht — niemals durch einen Framework-Wechsel. Archivierungstaugliche PDF/A-Ausgabe und PAdES-Baseline-Signierung (B-B und B-T) sind bereits in Core und auf dieselbe Weise über jede Oberfläche verfügbar.

Enterprise

Strukturiertes E-Invoicing (EN 16931) und tiefergehendes Compliance-Werkzeug sind ebenfalls Edition-Fähigkeiten, gleichermaßen identisch, welche Oberfläche auch immer die Engine aufruft, während die Konformitätsvalidierung selbst in Core ausgeliefert wird.

Zwei weitere Abgrenzungen sind es wert, klar benannt zu werden. Erstens verfolgt jede Bridge eine aktuelle Major-Version ihres Frameworks — Laravel, Symfony und CodeIgniter pinnen jeweils einen unterstützten Bereich, sodass „jedes Framework“ die unterstützte Version jedes einzelnen meint, nicht jede historische Veröffentlichung; behandeln Sie die eigene Dokumentation jedes Pakets als maßgeblich für seine API. Zweitens sind die Bridges Framework-Adapter, keine Rendering-Backends. Wenn ein Dokument eine vollständige Browser-Layout-Engine benötigt, ist das eine Renderer-Entscheidung, unabhängig davon, welches Framework die Engine aufgerufen hat.

  • Der Integrationsentscheidungsleitfaden — die Zuordnung von Anwendungsfall zu Paket, einschließlich Renderern und der Connect-Service-Oberfläche, wenn Sie entscheiden statt standardisieren müssen.
  • Open Core, kein Lock-in — warum die Engine der Wert ist und die Bridges dünn sind, sodass die Standardisierung Sie nicht einsperrt.
  • Die HTML-Pipeline — was die In-Process-Engine abdeckt, sodass Sie wissen, wann ein Browser-Renderer die getrennte Frage ist.
  • Die PHP-8.4-Grundlagen — die Laufzeit-Untergrenze, die jede Bridge und der Standalone-Pfad teilen.
  • Core-Enginenextpdf/core, die framework-agnostische PDF-2.0-Engine, auf der jede Bridge und der Standalone-Pfad aufbauen.
  • Framework-Bridge — ein Integrationspaket (Laravel, Symfony, CodeIgniter), das die Engine an die Idiome eines Frameworks anpasst — Fassade, Factory, Response, warteschlangenbasierter Job — ohne ihre Fähigkeiten zu ändern.
  • Standalone-Pfad — die direkte Nutzung der Core-Engine, ohne Framework, indem Sie selbst ein Document konstruieren; der Weg für CLI-Werkzeuge, Daemons und Bibliotheken.
  • Wegwerfbares Dokument — der Einweg-Document-Vertrag: aufbauen, ausgeben, verwerfen. Jede Container-Auflösung gibt ein frisches zurück, sodass in einem langlebigen Worker kein Zustand zwischen Anfragen leckt.
  • PAdES — PDF Advanced Electronic Signatures, die ETSI-Profilfamilie für die PDF-Signierung. Die Baseline-Signierung (B-B und B-T) ist in Core; die Langzeitvalidierung (B-LT und B-LTA) ist eine Fähigkeit der fortgeschrittenen Editionen. Beide werden über jede Oberfläche erreicht, ausführlich behandelt auf den Signierungsseiten.