Zum Inhalt springen

NextPDF für CodeIgniter 4

nextpdf/codeigniter verbindet die NextPDF-PDF-Engine über die frameworkeigene Services-Schicht mit einer CodeIgniter 4-Anwendung. Sie erstellen PDF-Dokumente in Controllern, Jobs oder Commands und geben sie anschließend als native CodeIgniter-HTTP-Antworten zurück.

Terminal-Fenster
composer require nextpdf/codeigniter

Die composer.json des Pakets setzt php >=8.4 <9.0, nextpdf/core ^3.0 || ^5.2 und codeigniter4/framework ^4.6 voraus. Außerdem empfiehlt sie nextpdf/artisan, nextpdf/premium und codeigniter4/queue. Die vollständige Anforderungstabelle, die optionalen Pakete und die Verifizierungsschritte finden Sie unter /integrations/codeigniter/install/.

NextPDF ist eine PDF 2.0-Engine in PHP 8.4. Die Core-Engine (nextpdf/core) ist frameworkunabhängig. Sie kennt weder HTTP noch Routing oder das Verdrahten von Abhängigkeiten. nextpdf/codeigniter ist der Adapter, der die Engine mit einer CodeIgniter 4-Anwendung verbindet. Mit dem Adapter müssen Sie Registries, Factories oder das Antwort-Handling nicht mehr selbst verdrahten.

Das Paket fügt einer CodeIgniter 4-Anwendung vier Dinge hinzu:

  • Eine Services-Klasse (NextPDF\CodeIgniter\Config\Services), die CodeIgniter automatisch erkennt und die benannte Dienste bereitstellt: fontRegistry, imageRegistry, documentFactory, pdfDocument, pdf, tsaClient und pdfSigner.
  • Eine Pdf-Bibliothek (NextPDF\CodeIgniter\Libraries\Pdf) — eine High-Level-Controller-API. Sie kapselt ein einzelnes, kurzlebiges Dokument und erzeugt daraus mit einem einzigen Aufruf eine Antwort.
  • Ein PdfResponse-Helfer (NextPDF\CodeIgniter\Http\PdfResponse), der eine CodeIgniter-DownloadResponse für die Inline-Vorschau oder den Download erzeugt. Er hängt einen festen Satz von Headern zur Härtung der Antwort an.
  • Zwei globale Helferfunktionen, pdf() und pdf_document(). Sie werden über den Composer-files-Autoload-Eintrag und den Registrar des Pakets registriert.

Das Paket erkennt außerdem optionale NextPDF-Erweiterungen während des Dokument-Builds. Wenn nextpdf/artisan installiert und ein Chrome-Binary konfiguriert ist, erhält das Dokument den Chrome-Renderer. Wenn NextPDF Pro installiert ist, werden PDF/A-Ausgabe und digitales Signieren über dieselbe Services-Oberfläche erreichbar. Die Erkennung erfolgt nur bedingt und ohne Ausgabe. Das Paket verlangt niemals eine Erweiterung, die nicht vorhanden ist.

Warum eine Services-Klasse und keine Container-Bindung

Abschnitt betitelt „Warum eine Services-Klasse und keine Container-Bindung“

CodeIgniter 4 liefert keinen PSR-11-Container für Dependency Injection mit. Stattdessen nutzt es einen Services-Locator. Ein Services-Locator ist eine Klasse mit statischen Factory-Methoden, die das Framework erkennt und deren Methoden jeweils entweder eine gemeinsam genutzte oder eine neue Instanz zurückgeben. PSR-11 behandelt das Service-Locator-Muster — also das Hineinreichen eines Containers in ein Objekt, damit das Objekt seine eigenen Abhängigkeiten abrufen kann — ausdrücklich als unerwünscht (PSR-11 §1.3, modales SHOULD NOT). Das Paket folgt der Locator-Konvention von CodeIgniter. Es hält die Locator-Oberfläche zudem minimal und explizit: Jeder Dienst ist eine benannte Factory-Methode mit einem bool $getShared-Parameter, und aufrufender Code erhält konkrete Objekte statt eines Container-Handles.

Dieses Design macht die CodeIgniter-Integration konsistent mit den Laravel- und Symfony-Integrationen. Jede dieser Integrationen stellt dieselben logischen Dienste über die Idiome des jeweiligen Frameworks bereit.

EinstiegspunktTypGibt zurückLebensdauer
Services::fontRegistry()DienstFontRegistryInterfacegemeinsam genutzt (aufgewärmt, dann gesperrt)
Services::imageRegistry()DienstImageRegistrygemeinsam genutzt (begrenzter LRU-Cache)
Services::documentFactory()DienstDocumentFactoryInterfacegemeinsam genutzt (zustandslos)
Services::pdfDocument(false)DienstNextPDF\Core\Documentfrisch pro Aufruf
Services::pdf(false)DienstNextPDF\CodeIgniter\Libraries\Pdffrisch pro Aufruf
Services::tsaClient()Dienst?TsaClientgemeinsam genutzt; null, wenn keine TSA-URL
Services::pdfSigner(false)Dienst?SignerInterfacefrisch; null, wenn das Signieren deaktiviert ist
pdf()HelferPdffrisch pro Aufruf
pdf_document()HelferDocumentfrisch pro Aufruf
PdfResponse::inline() / download()statischDownloadResponsepro Aufruf
GeneratePdfJobQueue-Jobeiner pro Dispatch

Ein Controller gibt mit drei Codezeilen ein PDF zurück. Services::pdf() liefert eine frische Pdf-Bibliothek, die ein frisches Dokument kapselt. download() erzeugt anschließend eine CodeIgniter-DownloadResponse.

<?php
declare(strict_types=1);
namespace App\Controllers;
use CodeIgniter\HTTP\DownloadResponse;
use NextPDF\CodeIgniter\Config\Services;
final class InvoiceController extends BaseController
{
public function download(int $id): DownloadResponse
{
$pdf = Services::pdf();
$pdf->document()->addPage();
$pdf->document()->cell(0, 10, "Invoice #{$id}");
return $pdf->download("invoice-{$id}.pdf");
}
}

Die vollständige lauffähige Anleitung finden Sie unter /integrations/codeigniter/quickstart/. Sie deckt Routing, die Inline-Vorschau und die Helfervarianten pdf() und pdf_document() ab.

In Produktion fordern Sie mit Services::pdf(false) eine nicht gemeinsam genutzte Instanz an. Fangen Sie die einzelne Basis-Exception NextPDF\Exception\NextPdfException ab; jeder Fehler im Core und in den Erweiterungen erbt von ihr. Protokollieren Sie den Fehler mit Kontext, statt ihn zu unterdrücken.

try {
$pdf = Services::pdf(false);
$pdf->document()->addPage();
$pdf->document()->cell(0, 10, "Invoice #{$id}");
return $pdf->download("invoice-{$id}.pdf");
} catch (NextPdfException $e) {
$logger->error('pdf.invoice.failed', [
'invoice_id' => $id,
'exception' => $e::class,
'message' => $e->getMessage(),
]);
return $this->response
->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR)
->setJSON(['error' => 'pdf_generation_failed', 'invoice_id' => $id]);
}

Den vollständigen Produktions-Controller finden Sie unter /integrations/codeigniter/production-usage/. Er ergänzt Observability-Timing, workersichere Lebensdauern und asynchrone Generierung.

  • Die Font- und Image-Registries sind Singletons mit Prozesslebensdauer. Ein Dokument wird niemals gemeinsam genutzt. pdfDocument und pdf geben bei jedem Aufruf eine frische Instanz zurück, sodass Inhalte aus einer Anfrage nicht in eine andere gelangen können. Services::pdf(false) und pdf() geben beide eine frische Bibliothek zurück, die ein frisches Dokument kapselt.
  • Das Paket setzt die PHP-Erweiterungen mbstring und zlib voraus. Die Font-Registry prüft dies einmal pro Prozess. Fehlt eine der beiden Erweiterungen, löst die Font-Registry einen Laufzeitfehler aus, der die fehlende Erweiterung benennt.
  • Das Verhalten optionaler Erweiterungen hängt davon ab, was in derselben Anwendung installiert ist. Ist nur nextpdf/core vorhanden, geben die Signatur- und PDF/A-Pfade null zurück oder werden übersprungen. Sie schlagen niemals mit einem Fehler fehl.

Die Integration verursacht gegenüber der Engine selbst keinen messbaren zusätzlichen Aufwand. Die Font-Registry wird einmal geparst und anschließend gesperrt. Die Image-Registry ist ein LRU-Cache, der durch die Einstellung imageCacheMb begrenzt wird (standardmäßig 50 MB). Die Kosten des PDF-Builds werden von der Core-Engine und dem Dokumentinhalt bestimmt, nicht vom Adapter. Das Budget pro Seite für diese Dokumentationssammlung beträgt 1500 ms Wall-Time / 128 MB Spitze. Konkrete Recipes legen ihr eigenes Budget im Front-Matter fest.

PdfResponse fügt jedem ausgegebenen PDF einen festen Satz von Response-Headern hinzu: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Content-Security-Policy: default-src 'none', X-Robots-Tag: noindex, nofollow und Referrer-Policy: no-referrer. Dateinamen werden bereinigt, und Nicht-ASCII-Namen werden mit einem erweiterten RFC 5987-Parameter ausgegeben. Der Queue-Job beschränkt Builder-Callables auf den Namespace App\PdfBuilders und begrenzt die Ausgabepfade auf WRITEPATH/pdfs/. Das vollständige Bedrohungsmodell finden Sie unter /integrations/codeigniter/security-and-operations/.

  • Die Modulerkennung stützt sich auf das PSR-4-Autoloading von Composer. Ein Namespace-Präfix wird auf ein Basisverzeichnis abgebildet, und der voll qualifizierte Klassenname wird auf einen Dateipfad abgebildet (PSR-4 §x1.x3).
  • Das Design der Services folgt der Locator-Leitlinie, die unter PSR-11 §1.3 erörtert wird.

NextPDF Core steht unter Apache-2.0. Digitale Signaturen, PDF/A-Archivierung und das Einbetten von Factur-X-E-Rechnungen werden von NextPDF Pro und NextPDF Enterprise bereitgestellt. Das CodeIgniter-Paket stellt die entsprechenden Dienstmethoden bereit. Diese Methoden geben null zurück, bis das passende Premium-Paket in derselben Anwendung installiert ist.

  • /integrations/codeigniter/install/ — das Paket installieren und verifizieren.
  • /integrations/codeigniter/quickstart/ — das erste PDF in einem Controller.
  • /integrations/codeigniter/configuration/ — alle Konfigurationsschlüssel.
  • /integrations/codeigniter/boot-and-discovery/ — wie CodeIgniter die Services-Klasse findet.
  • /integrations/codeigniter/integration/ — Verdrahtungsreferenz und Smoke-Test.