Pular para o conteúdo

NextPDF para CodeIgniter 4

nextpdf/codeigniter conecta o mecanismo Portable Document Format (PDF) do NextPDF a uma aplicação CodeIgniter 4 por meio da camada de Services do framework. Você cria documentos PDF em controllers, jobs ou commands e depois os retorna como respostas Hypertext Transfer Protocol (HTTP) nativas do CodeIgniter.

Terminal window
composer require nextpdf/codeigniter

No pacote, o composer.json exige php >=8.4 <9.0, nextpdf/core ^3.0 || ^5.2 e codeigniter4/framework ^4.6. Ele também sugere nextpdf/artisan, nextpdf/premium e codeigniter4/queue. Para ver a tabela completa de requisitos, pacotes opcionais e etapas de verificação, consulte /integrations/codeigniter/install/.

NextPDF é um mecanismo PDF 2.0 para PHP 8.4. O mecanismo principal (nextpdf/core) é agnóstico em relação ao framework. Ele não conhece HTTP, roteamento nem como as dependências são conectadas. O nextpdf/codeigniter é o adaptador que conecta o mecanismo a uma aplicação CodeIgniter 4. Com o adaptador instalado, você não precisa conectar registries, factories nem o tratamento de respostas por conta própria.

O pacote adiciona quatro coisas a um aplicativo CodeIgniter 4:

  • Uma classe Services (NextPDF\CodeIgniter\Config\Services) que o CodeIgniter descobre automaticamente. Ela expõe serviços nomeados: fontRegistry, imageRegistry, documentFactory, pdfDocument, pdf, tsaClient e pdfSigner.
  • Uma biblioteca Pdf (NextPDF\CodeIgniter\Libraries\Pdf) — uma application programming interface (API) de alto nível para controllers. Ela encapsula um único documento de uso único e o transforma em uma resposta em uma só chamada.
  • Um helper PdfResponse (NextPDF\CodeIgniter\Http\PdfResponse) que cria um DownloadResponse do CodeIgniter para visualização inline ou download. Ele anexa um conjunto fixo de cabeçalhos de proteção para a resposta.
  • Duas funções helper globais, pdf() e pdf_document(). Elas são registradas pela entrada de autoload files do Composer e pelo Registrar do pacote.

O pacote também detecta extensões opcionais do NextPDF ao criar um documento. Quando o nextpdf/artisan está instalado e um binário do Chrome está configurado, o documento recebe o renderizador do Chrome. Quando o NextPDF Pro está instalado, a saída PDF/A e a assinatura digital ficam disponíveis pela mesma superfície de Services. A detecção é condicional e silenciosa. O pacote nunca exige uma extensão ausente.

Por que uma classe Services e não um binding de container

Seção intitulada “Por que uma classe Services e não um binding de container”

O CodeIgniter 4 não vem com um container de injeção de dependências PSR-11. Em vez disso, ele usa um localizador de Services. Um localizador de Services é uma classe descoberta pelo framework com métodos de factory estáticos. Cada método retorna uma instância compartilhada ou uma nova instância. O PSR-11 desencoraja o padrão service-locator — passar um container para um objeto para que ele busque as próprias dependências — no PSR-11 §1.3 com o verbo modal SHOULD NOT. O pacote segue a convenção de localizador do CodeIgniter. Ele também mantém a superfície do localizador mínima e explícita: cada serviço é um método de factory nomeado com um parâmetro bool $getShared, e quem chama recebe objetos concretos em vez de um handle de container.

Esse design mantém a integração com o CodeIgniter consistente com as integrações com o Laravel e o Symfony. Cada integração expõe os mesmos serviços lógicos por meio das convenções do seu próprio framework.

Ponto de entradaTipoRetornaTempo de vida
Services::fontRegistry()serviçoFontRegistryInterfacecompartilhado (aquecido e, então, bloqueado)
Services::imageRegistry()serviçoImageRegistrycompartilhado (cache least recently used (LRU) limitado)
Services::documentFactory()serviçoDocumentFactoryInterfacecompartilhado (sem estado)
Services::pdfDocument(false)serviçoNextPDF\Core\Documentnovo a cada chamada
Services::pdf(false)serviçoNextPDF\CodeIgniter\Libraries\Pdfnovo a cada chamada
Services::tsaClient()serviço?TsaClientcompartilhado; null quando não há URL de timestamp authority (TSA)
Services::pdfSigner(false)serviço?SignerInterfacenovo; null quando a assinatura está desativada
pdf()helperPdfnovo a cada chamada
pdf_document()helperDocumentnovo a cada chamada
PdfResponse::inline() / download()estáticoDownloadResponsepor chamada
GeneratePdfJobjob de filaum por despacho

Um controller retorna um PDF em três linhas. O Services::pdf() retorna uma nova biblioteca Pdf, que encapsula um novo documento. Em seguida, o download() cria um DownloadResponse do 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");
}
}

O passo a passo executável completo está em /integrations/codeigniter/quickstart/. Ele cobre roteamento, visualização inline e as variações dos helpers pdf() e pdf_document().

Em produção, solicite uma instância não compartilhada com Services::pdf(false). Capture a única exceção base, NextPDF\Exception\NextPdfException; toda falha do core e das extensões estende essa classe. Registre a falha com contexto em vez de engolir o erro.

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]);
}

O controller de produção completo está em /integrations/codeigniter/production-usage/. Ele adiciona temporização de observabilidade, ciclos de vida seguros para workers e geração assíncrona.

  • Os registries de fontes e imagens são singletons com ciclo de vida do processo. Um documento nunca é compartilhado. pdfDocument e pdf retornam uma nova instância a cada chamada, de modo que uma requisição não pode vazar conteúdo para outra. Services::pdf(false) e pdf() retornam, ambos, uma nova biblioteca que encapsula um novo documento.
  • O pacote requer as extensões PHP mbstring e zlib. O registry de fontes as valida uma vez por processo. Se qualquer uma das extensões estiver ausente, o registry de fontes gera um erro em tempo de execução que identifica a extensão ausente.
  • O comportamento das extensões opcionais depende do que está instalado na mesma aplicação. Com apenas o nextpdf/core presente, os caminhos de assinatura e PDF/A retornam null ou são ignorados. Eles nunca falham de maneira ruidosa.

A integração não adiciona sobrecarga mensurável além do próprio mecanismo. O registry de fontes é analisado uma vez e depois bloqueado. O registry de imagens é um cache LRU limitado pela configuração imageCacheMb (50 MB por padrão). O mecanismo principal e o conteúdo do documento determinam o custo de criação do PDF, não o adaptador. O orçamento por página para este conjunto de documentação é de 1500 ms de wall / 128 MB de pico. Receitas reais definem o próprio orçamento no front-matter.

PdfResponse anexa um conjunto fixo de cabeçalhos de resposta 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 e Referrer-Policy: no-referrer. Os nomes de arquivo são sanitizados, e nomes não ASCII são emitidos com um parâmetro estendido de Request for Comments (RFC) 5987. O job de fila restringe os callables de construção ao namespace App\PdfBuilders e confina os caminhos de saída a WRITEPATH/pdfs/. Consulte /integrations/codeigniter/security-and-operations/ para o modelo de ameaças completo.

  • A descoberta de módulos depende do autoload PSR-4 do Composer. Um prefixo de namespace mapeia para um diretório base, e o nome de classe totalmente qualificado mapeia para um caminho de arquivo (PSR-4 §x1.x3).
  • O design de Services segue a orientação de localizador discutida em PSR-11 §1.3.

O core do NextPDF é Apache-2.0. Assinaturas digitais, arquivamento PDF/A e incorporação de nota fiscal eletrônica Factur-X são fornecidos pelo NextPDF Pro e pelo NextPDF Enterprise. O pacote do CodeIgniter expõe os métodos de serviço correspondentes. Esses métodos retornam null até que o pacote Premium correspondente seja instalado na mesma aplicação.

  • /integrations/codeigniter/install/ — instale e verifique o pacote.
  • /integrations/codeigniter/quickstart/ — primeiro PDF em um controller.
  • /integrations/codeigniter/configuration/ — cada chave de configuração.
  • /integrations/codeigniter/boot-and-discovery/ — como o CodeIgniter encontra a classe Services.
  • /integrations/codeigniter/integration/ — referência de encadeamento e teste de fumaça.