NextPDF per CodeIgniter 4
In sintesi
Sezione intitolata “In sintesi”nextpdf/codeigniter collega il motore PDF NextPDF a un’applicazione CodeIgniter 4 tramite il livello Services del framework. I documenti PDF possono essere costruiti in controller, job o comandi e poi restituiti come risposte HTTP native di CodeIgniter.
Installazione
Sezione intitolata “Installazione”composer require nextpdf/codeigniterIl file composer.json del pacchetto richiede php >=8.4 <9.0,
nextpdf/core ^3.0 || ^5.2 e codeigniter4/framework ^4.6. Inoltre
suggerisce nextpdf/artisan, nextpdf/premium e codeigniter4/queue. La tabella completa dei requisiti, l’elenco dei pacchetti facoltativi e i passaggi di verifica sono disponibili in /integrations/codeigniter/install/.
Panoramica concettuale
Sezione intitolata “Panoramica concettuale”NextPDF è un motore PDF 2.0 in PHP 8.4. Il motore principale (nextpdf/core) è indipendente dal framework. Non conosce HTTP, routing o cablaggio delle dipendenze. nextpdf/codeigniter è l’adattatore che collega il motore a un’applicazione CodeIgniter 4. Usando l’adattatore, non è necessario cablare manualmente registry, factory o gestione delle risposte.
Il pacchetto aggiunge quattro elementi a un’applicazione CodeIgniter 4:
- Una classe Services (
NextPDF\CodeIgniter\Config\Services) che CodeIgniter rileva automaticamente e che espone i servizi denominati:fontRegistry,imageRegistry,documentFactory,pdfDocument,pdf,tsaClientepdfSigner. - Una libreria
Pdf(NextPDF\CodeIgniter\Libraries\Pdf): un’API per controller di alto livello. Incapsula un singolo documento monouso e lo trasforma in una risposta con una sola chiamata. - Un helper
PdfResponse(NextPDF\CodeIgniter\Http\PdfResponse) che produce unDownloadResponsedi CodeIgniter per l’anteprima in linea o il download. Aggiunge un insieme fisso di header di hardening per la risposta. - Due funzioni helper globali,
pdf()epdf_document(). Sono registrate tramite la vocefilesdell’autoload di Composer e ilRegistrardel pacchetto.
Il pacchetto rileva anche le estensioni facoltative di NextPDF al momento della creazione del documento. Quando nextpdf/artisan è installato ed è configurato un binario di Chrome, il documento acquisisce il renderer Chrome. Quando è installato NextPDF Pro, l’output PDF/A e la firma digitale diventano disponibili attraverso la stessa superficie Services. Il rilevamento è condizionale e silenzioso. Il pacchetto non richiede mai un’estensione assente.
Perché una classe Services e non un binding di container
Sezione intitolata “Perché una classe Services e non un binding di container”CodeIgniter 4 non include un container di dependency injection PSR-11. Usa invece un locator Services. Si tratta di una classe con metodi factory statici, rilevata dal framework, in cui ciascun metodo restituisce un’istanza condivisa oppure una nuova istanza. PSR-11 sconsiglia esplicitamente il pattern service-locator, ossia il passaggio di un container a un oggetto affinché possa recuperare le proprie dipendenze (PSR-11 §1.3, modale SHOULD NOT). Il pacchetto segue la convenzione del locator di CodeIgniter. Mantiene inoltre la superficie del locator minima ed esplicita: ogni servizio è un metodo factory denominato con un parametro bool $getShared e i chiamanti ricevono oggetti concreti anziché un handle del container.
Questa scelta progettuale mantiene l’integrazione CodeIgniter coerente con le integrazioni Laravel e Symfony. Ciascuna integrazione espone gli stessi servizi logici attraverso l’idioma del proprio framework.
Superficie API
Sezione intitolata “Superficie API”| Punto di ingresso | Tipo | Restituisce | Durata |
|---|---|---|---|
Services::fontRegistry() | servizio | FontRegistryInterface | condiviso (preriscaldato, poi bloccato) |
Services::imageRegistry() | servizio | ImageRegistry | condiviso (cache LRU limitata) |
Services::documentFactory() | servizio | DocumentFactoryInterface | condiviso (stateless) |
Services::pdfDocument(false) | servizio | NextPDF\Core\Document | nuovo a ogni chiamata |
Services::pdf(false) | servizio | NextPDF\CodeIgniter\Libraries\Pdf | nuovo a ogni chiamata |
Services::tsaClient() | servizio | ?TsaClient | condiviso; null in assenza di URL TSA |
Services::pdfSigner(false) | servizio | ?SignerInterface | nuovo; null quando la firma è disabilitata |
pdf() | helper | Pdf | nuovo a ogni chiamata |
pdf_document() | helper | Document | nuovo a ogni chiamata |
PdfResponse::inline() / download() | statico | DownloadResponse | a ogni chiamata |
GeneratePdfJob | job di coda | — | uno per dispatch |
Esempio di codice — Avvio rapido
Sezione intitolata “Esempio di codice — Avvio rapido”Un controller restituisce un PDF in tre righe. Services::pdf() crea una nuova libreria Pdf che incapsula un nuovo documento. download() produce quindi un DownloadResponse di CodeIgniter.
<?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"); }}La procedura completa ed eseguibile è disponibile in /integrations/codeigniter/quickstart/. Copre il routing, l’anteprima in linea e le varianti degli helper pdf() e pdf_document().
Esempio di codice — Produzione
Sezione intitolata “Esempio di codice — Produzione”In produzione, richiedere un’istanza non condivisa con Services::pdf(false). Catturare l’unica eccezione di base NextPDF\Exception\NextPdfException; ogni errore del core e delle estensioni la estende. Registrare l’errore con il relativo contesto anziché ignorarlo silenziosamente.
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]);}Il controller di produzione completo è disponibile in /integrations/codeigniter/production-usage/. Aggiunge misurazioni temporali per l’osservabilità, durate sicure per i worker e la generazione asincrona.
Casi limite e insidie
Sezione intitolata “Casi limite e insidie”- I registry di font e immagini sono singleton per la durata del processo. Un documento non viene mai condiviso.
pdfDocumentepdfrestituiscono una nuova istanza a ogni chiamata, in modo che una richiesta non possa far trapelare contenuti verso un’altra.Services::pdf(false)epdf()restituiscono entrambi una nuova libreria che incapsula un nuovo documento. - Il pacchetto richiede le estensioni PHP
mbstringezlib. Il registry dei font ne verifica la presenza una volta per processo. Se una delle due estensioni è assente, il registry dei font genera un errore di runtime che indica l’estensione mancante. - Il comportamento delle estensioni facoltative dipende da ciò che è installato nella stessa applicazione. Con il solo
nextpdf/corepresente, i percorsi di firma e PDF/A restituiscononullo vengono saltati. Non generano mai errori espliciti.
Prestazioni
Sezione intitolata “Prestazioni”L’integrazione non aggiunge alcun overhead misurabile oltre a quello del motore stesso. Il registry dei font viene analizzato una sola volta e poi bloccato. Il registry delle immagini è una cache LRU limitata dall’impostazione imageCacheMb (50 MB per impostazione predefinita). Il costo di creazione del PDF dipende dal motore principale e dal contenuto del documento, non dall’adattatore. Il budget per pagina di questo set di documentazione è di 1500 ms di tempo reale / 128 MB di picco. Le ricette per casi reali definiscono il proprio budget nel front-matter.
Note sulla sicurezza
Sezione intitolata “Note sulla sicurezza”PdfResponse aggiunge un insieme fisso di header di risposta a ogni PDF che emette: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Content-Security-Policy: default-src 'none', X-Robots-Tag: noindex, nofollow e Referrer-Policy: no-referrer. I nomi dei file vengono sanitizzati e i nomi non ASCII vengono emessi con un parametro esteso RFC 5987. Il job di coda limita i builder callable al namespace App\PdfBuilders e confina i percorsi di output a WRITEPATH/pdfs/. Per il modello di minaccia completo, vedere /integrations/codeigniter/security-and-operations/.
Conformità
Sezione intitolata “Conformità”- Il rilevamento dei moduli si basa sull’autoloading PSR-4 di Composer. Un prefisso di namespace viene mappato a una directory di base e il nome di classe completo viene mappato a un percorso di file (PSR-4 §x1.x3).
- La progettazione di Services segue le indicazioni sul locator descritte in PSR-11 §1.3.
Contesto commerciale
Sezione intitolata “Contesto commerciale”Il core di NextPDF è distribuito con licenza Apache-2.0. Le firme digitali, l’archiviazione PDF/A e l’incorporamento di fatture elettroniche Factur-X sono forniti da NextPDF Pro e NextPDF Enterprise. Il pacchetto CodeIgniter espone i metodi di servizio corrispondenti. Tali metodi restituiscono null finché il pacchetto Premium corrispondente non viene installato nella stessa applicazione.
Vedere anche
Sezione intitolata “Vedere anche”- /integrations/codeigniter/install/ — installazione e verifica del pacchetto.
- /integrations/codeigniter/quickstart/ — primo PDF in un controller.
- /integrations/codeigniter/configuration/ — ogni chiave di configurazione.
- /integrations/codeigniter/boot-and-discovery/ — come CodeIgniter individua la classe Services.
- /integrations/codeigniter/integration/ — riferimento di cablaggio e smoke test.