NextPDF para CodeIgniter 4
De un vistazo
Sección titulada «De un vistazo»nextpdf/codeigniter conecta el motor PDF de NextPDF con una aplicación CodeIgniter 4 mediante la propia capa de Services del framework. Permite construir documentos PDF en controladores, jobs o comandos y devolverlos después como respuestas HTTP nativas de CodeIgniter.
Instalación
Sección titulada «Instalación»composer require nextpdf/codeigniterEl composer.json del paquete requiere php >=8.4 <9.0,
nextpdf/core ^3.0 || ^5.2 y codeigniter4/framework ^4.6. También
sugiere nextpdf/artisan, nextpdf/premium y codeigniter4/queue. La tabla completa de requisitos, paquetes opcionales y pasos de verificación está en /integrations/codeigniter/install/.
Resumen conceptual
Sección titulada «Resumen conceptual»NextPDF es un motor PDF 2.0 para PHP 8.4. El motor central (nextpdf/core) es independiente del framework: no sabe nada de HTTP, enrutamiento ni cableado de dependencias. nextpdf/codeigniter es el adaptador que conecta el motor con una aplicación CodeIgniter 4. Con el adaptador instalado, no hace falta cablear manualmente los registries, las factories ni el manejo de respuestas.
El paquete añade cuatro cosas a una aplicación CodeIgniter 4:
- Una clase Services (
NextPDF\CodeIgniter\Config\Services) que CodeIgniter detecta automáticamente y que expone servicios con nombre:fontRegistry,imageRegistry,documentFactory,pdfDocument,pdf,tsaClientypdfSigner. - Una biblioteca
Pdf(NextPDF\CodeIgniter\Libraries\Pdf): una API de alto nivel para controladores. Envuelve un documento de un solo uso y lo convierte en una respuesta con una sola llamada. - Un helper
PdfResponse(NextPDF\CodeIgniter\Http\PdfResponse) que produce unDownloadResponsede CodeIgniter para vista previa en línea o descarga. Adjunta un conjunto fijo de cabeceras de endurecimiento para la respuesta. - Dos funciones auxiliares globales,
pdf()ypdf_document(). Se registran a través de la entrada de autocargafilesde Composer y delRegistrardel paquete.
El paquete también detecta extensiones opcionales de NextPDF al construir el documento. Cuando nextpdf/artisan está instalado y hay un binario de Chrome configurado, el documento incorpora el renderer de Chrome. Cuando NextPDF Pro está instalado, la salida PDF/A y la firma digital quedan disponibles a través de la misma superficie de Services. La detección es condicional y silenciosa. El paquete nunca requiere una extensión que no esté presente.
Por qué usar una clase Services y no un binding del contenedor
Sección titulada «Por qué usar una clase Services y no un binding del contenedor»CodeIgniter 4 no incluye un contenedor de inyección de dependencias PSR-11. En su lugar, usa un localizador de servicios. Un localizador de servicios es una clase con métodos de fábrica estáticos, detectada por el framework, en la que cada método devuelve una instancia compartida o una nueva. PSR-11 trata explícitamente como desaconsejado el patrón de localizador de servicios —pasar un contenedor a un objeto para que el objeto recupere sus propias dependencias— (PSR-11 §1.3, modal SHOULD NOT). El paquete sigue la convención de localizador de CodeIgniter. Además, mantiene la superficie del localizador mínima y explícita: cada servicio es un método de fábrica con nombre y un parámetro bool $getShared, y quienes lo llaman reciben objetos concretos en lugar de un manejador del contenedor.
Este diseño mantiene la integración con CodeIgniter alineada con las integraciones de Laravel y Symfony. Cada una de esas integraciones expone los mismos servicios lógicos a través de las convenciones de su propio framework.
Superficie de la API
Sección titulada «Superficie de la API»| Punto de entrada | Tipo | Devuelve | Vida útil |
|---|---|---|---|
Services::fontRegistry() | servicio | FontRegistryInterface | compartido (precalentado y luego bloqueado) |
Services::imageRegistry() | servicio | ImageRegistry | compartido (caché LRU acotada) |
Services::documentFactory() | servicio | DocumentFactoryInterface | compartido (sin estado) |
Services::pdfDocument(false) | servicio | NextPDF\Core\Document | nuevo en cada llamada |
Services::pdf(false) | servicio | NextPDF\CodeIgniter\Libraries\Pdf | nuevo en cada llamada |
Services::tsaClient() | servicio | ?TsaClient | compartido; null cuando no hay URL de TSA |
Services::pdfSigner(false) | servicio | ?SignerInterface | nuevo; null cuando la firma está deshabilitada |
pdf() | helper | Pdf | nuevo en cada llamada |
pdf_document() | helper | Document | nuevo en cada llamada |
PdfResponse::inline() / download() | estático | DownloadResponse | por llamada |
GeneratePdfJob | job de cola | — | uno por despacho |
Ejemplo de código: inicio rápido
Sección titulada «Ejemplo de código: inicio rápido»Un controlador devuelve un PDF en tres líneas. Services::pdf() produce una biblioteca Pdf nueva que envuelve un documento nuevo. Luego, download() produce un DownloadResponse de 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"); }}El recorrido ejecutable completo está en /integrations/codeigniter/quickstart/. Cubre el enrutamiento, la vista previa en línea y las variaciones de los helpers pdf() y pdf_document().
Ejemplo de código: producción
Sección titulada «Ejemplo de código: producción»En producción, se debe solicitar una instancia no compartida con Services::pdf(false). Se debe capturar la única excepción base NextPDF\Exception\NextPdfException; todo fallo del núcleo y de las extensiones la extiende. El fallo debe registrarse con su contexto, en lugar de ocultar el error.
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]);}El controlador de producción completo está en /integrations/codeigniter/production-usage/. Añade instrumentación de observabilidad, ciclos de vida seguros para workers y generación asíncrona.
Casos límite y trampas
Sección titulada «Casos límite y trampas»- Los registries de fuentes e imágenes son singletons con vida útil del proceso. Un documento nunca se comparte.
pdfDocumentypdfdevuelven una instancia nueva en cada llamada, de modo que una solicitud no pueda filtrar contenido a otra.Services::pdf(false)ypdf()devuelven ambos una biblioteca nueva que envuelve un documento nuevo. - El paquete requiere las extensiones de PHP
mbstringyzlib. El registry de fuentes valida esto una vez por proceso. Si falta cualquiera de las dos extensiones, el registry de fuentes lanza un error en tiempo de ejecución que indica la extensión que falta. - El comportamiento de las extensiones opcionales depende de lo que esté instalado en la misma aplicación. Con solo
nextpdf/corepresente, las rutas de firma y de PDF/A devuelvennullo se omiten. Nunca fallan de forma ruidosa.
Rendimiento
Sección titulada «Rendimiento»La integración no añade ninguna sobrecarga medible más allá del propio motor. El registry de fuentes se analiza una vez y luego queda bloqueado. El registry de imágenes es una caché LRU acotada por el ajuste imageCacheMb (50 MB de forma predeterminada). El coste de construir el PDF lo determinan el motor central y el contenido del documento, no el adaptador. El presupuesto por página de este conjunto de documentación es de 1500 ms de tiempo real / 128 MB de pico. Las recipes reales fijan su propio presupuesto en el front-matter.
Notas de seguridad
Sección titulada «Notas de seguridad»PdfResponse adjunta un conjunto fijo de cabeceras de respuesta a cada PDF que emite: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Content-Security-Policy: default-src 'none', X-Robots-Tag: noindex, nofollow y Referrer-Policy: no-referrer. Los nombres de archivo se sanean, y los nombres no ASCII se emiten con un parámetro extendido RFC 5987. El job de cola restringe los callables de construcción al espacio de nombres App\PdfBuilders y confina las rutas de salida a WRITEPATH/pdfs/. El modelo de amenazas completo está en /integrations/codeigniter/security-and-operations/.
Conformidad
Sección titulada «Conformidad»- La detección de módulos se basa en la autocarga PSR-4 de Composer. Un prefijo de espacio de nombres se asigna a un directorio base, y el nombre de clase completamente cualificado se asigna a una ruta de archivo (PSR-4 §x1.x3).
- El diseño de Services sigue la guía sobre localizadores descrita en PSR-11 §1.3.
Contexto comercial
Sección titulada «Contexto comercial»El núcleo de NextPDF es Apache-2.0. NextPDF Pro y NextPDF Enterprise proporcionan las firmas digitales, el archivado PDF/A y la incrustación de facturas electrónicas Factur-X. El paquete de CodeIgniter expone los métodos de servicio correspondientes. Esos métodos devuelven null hasta que el paquete Premium correspondiente esté instalado en la misma aplicación.
Véase también
Sección titulada «Véase también»- /integrations/codeigniter/install/ — instala y verifica el paquete.
- /integrations/codeigniter/quickstart/ — tu primer PDF desde un controlador.
- /integrations/codeigniter/configuration/ — cada clave de configuración.
- /integrations/codeigniter/boot-and-discovery/ — cómo encuentra CodeIgniter la clase Services.
- /integrations/codeigniter/integration/ — referencia de cableado y prueba de humo.