Um motor, todos os frameworks
Spec: PSR-11 Container, §1.1.2PSR-11 Container §1.1.2Spec: PSR-4 Autoloader, §3PSR-4 Autoloader §3
Visão geral
Seção intitulada “Visão geral”A maioria dos parques PHP em crescimento acaba com mais de um framework. O NextPDF é um único motor de PDF que encontra cada um deles em seus próprios termos: bridges idiomáticas para Laravel, Symfony e CodeIgniter, mais um caminho standalone para código que não roda em nenhum deles. O modelo de documento é compartilhado. Só muda a forma como você o chama.
Por que isso importa
Seção intitulada “Por que isso importa”Uma biblioteca de PDF diferente por stack é um imposto silencioso. Cada uma tem suas próprias peculiaridades, seu próprio tratamento de fontes, sua própria ideia do que “válido” significa. Uma fatura que renderiza corretamente a partir do serviço Laravel pode renderizar de forma sutilmente diferente a partir do worker Symfony, porque uma biblioteca diferente a desenhou. Agora o seu alvo de arquivamento, o posicionamento da sua assinatura e suas tags de acessibilidade dependem de qual equipe entregou o documento. O relatório de bug diz “o PDF está errado”, e a resposta depende de qual dos três motores o produziu.
Padronizar em um único motor faz essa superfície colapsar. Há um único lugar onde um perfil PDF/A é decidido, um pipeline de fontes para certificar, um validador para confiar. O framework em que você por acaso está deixa de ser uma variável na questão de o documento estar correto.
A versão curta
Seção intitulada “A versão curta”- O motor core é agnóstico de framework.
nextpdf/corenão sabe nada sobre HTTP, roteamento ou wiring de container. Ele é um motor de PDF 2.0 e nada além disso. - Cada bridge adapta, ela não reimplementa. Os pacotes Laravel, Symfony e CodeIgniter lhe dão um facade ou factory, um helper de resposta HTTP e um caminho de geração enfileirado ou assíncrono — sobre o mesmo motor.
- Uma bridge segue o seu framework, não o seu documento. Ela muda como você chama o motor, nunca o que o motor pode produzir.
- O standalone está sempre disponível. Uma ferramenta CLI, um daemon ou uma biblioteca não tem framework do qual fazer bridge; ela constrói um documento diretamente.
- Um único modelo de documento viaja por todos os quatro. Os mesmos value objects, enums e contrato de saída aparecem em todo lugar, então um documento se move entre pontos de chamada inalterado.
Como o NextPDF aborda isso
Seção intitulada “Como o NextPDF aborda isso”A arquitetura é uma divisão deliberada. O motor é o ativo; a bridge é um adaptador fino que fala os idiomas de um framework. Uma bridge registra um pequeno namespace sobre o core compartilhado por meio do autoloading padrão (Spec: PSR-4 Autoloader, §3PSR-4 Autoloader §3) e devolve um documento por meio do contrato de container (Spec: PSR-11 Container, §1.1.2PSR-11 Container §1.1.2). Esse contrato é o herói silencioso aqui: ele permite que duas resoluções do mesmo identificador retornem instâncias diferentes, que é exatamente como uma bridge lhe dá um documento novo e descartável por requisição, mantendo o registro de fontes parseadas e o cache de imagens como singletons de escopo de processo. Workers de vida longa — Octane, RoadRunner, Swoole, Messenger — obtêm o parsing de fontes amortizado sem vazamento de estado entre requisições, por construção.
Os quatro idiomas diferem apenas na superfície:
- Core enginenextpdf/core — the framework-agnostic PDF 2.0 engine; the single shared document model, value objects, and output contract.
- Laravel bridgenextpdf/laravel — auto-discovered provider, a Pdf facade, a PdfResponse helper, and a queued GeneratePdfJob.
- Symfony bridgenextpdf/symfony — an auto-registered bundle, an injectable PdfFactory, a PdfResponse, and an optional Messenger handler.
- CodeIgniter bridgenextpdf/codeigniter — a service and pdf() helper, a Pdf library over a disposable Document, and a PdfResponse.
- StandaloneNo framework to bridge from — construct a Document directly in a CLI tool, daemon, or library.
Leia o diagrama da esquerda para a direita e a lição é a simetria. Toda
superfície resolve para o mesmo Document. O facade Laravel, o factory Symfony,
o serviço CodeIgniter e o construtor standalone são quatro portas para uma única
sala.
Exemplo prático
Seção intitulada “Exemplo prático”As mesmas três linhas de intenção, expressas em cada idioma. O corpo que constrói o documento — páginas, fontes, células, assinatura, conformidade — é idêntico nos quatro, porque é o mesmo motor.
<?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();As primeiras linhas são a única diferença. Tudo o que vem depois é portátil: mova um serviço de construção de documentos do Symfony para um worker standalone e o código de renderização não muda, porque o contrato do qual ele depende não mudou.
Equívoco comum
Seção intitulada “Equívoco comum”A suposição frequente é que a bridge do framework destrava capacidades — que a
validação de assinatura de longo prazo ou o faturamento eletrônico estruturado
chega porque você instalou nextpdf/laravel em vez de chamar o motor
diretamente. Não chega. Uma bridge muda o ponto de chamada, nunca o alcance do
motor. Capacidades core como a saída PDF/A e a assinatura baseline PAdES são de
código aberto e alcançam toda superfície; capacidades avançadas são destravadas
por uma edição e ficam então disponíveis por meio de qualquer bridge ou do
caminho standalone igualmente. Escolher uma integração de framework não é
escolher um conjunto de recursos.
O equívoco espelhado é que “um motor” deve significar um único caminho de renderização para todo documento. Não significa. O motor in-process renderiza PDF diretamente; quando um documento genuinamente precisa de um motor de layout de nível navegador, um pacote renderizador cuida disso. Renderização e invocação são eixos separados — o guia de decisão de integração é o lugar que os mapeia.
Limites e fronteiras
Seção intitulada “Limites e fronteiras”Uma bridge não expande o que o motor pode renderizar. Esse é o limite honesto, e é o ponto: a capacidade vive no core e no tier, não no adaptador por meio do qual você a alcança.
| Edition | Availability |
|---|---|
| Core | Toda bridge (Laravel, Symfony, CodeIgniter) e o caminho standalone são Apache-2.0 e funcionam sobre o Core. Elas adaptam ou expõem o motor; elas não restringem recursos e não mudam o que ele pode produzir. |
| Pro | Capacidades avançadas como a validação de assinatura de longo prazo (PAdES B-LT e B-LTA) são destravadas por uma edição, e então alcançadas de forma idêntica por meio de qualquer bridge ou standalone — nunca trocando de framework. A saída PDF/A de arquivamento e a assinatura baseline PAdES (B-B e B-T) já estão no Core, disponíveis da mesma forma por meio de toda superfície. |
| Enterprise | O faturamento eletrônico estruturado (EN 16931) e a ferramenta de compliance mais profunda também são capacidades de edição, igualmente as mesmas seja qual for a superfície que chama o motor, enquanto a própria validação de conformidade vem no Core. |
Duas fronteiras adicionais valem ser ditas com clareza. Primeiro, cada bridge acompanha um major atual de seu framework — Laravel, Symfony e CodeIgniter cada um fixa um intervalo suportado, então “todos os frameworks” significa a versão suportada de cada um, não toda release histórica; trate a documentação de cada pacote como autoritativa para sua API. Segundo, as bridges são adaptadores de framework, não backends de renderização. Se um documento precisa de um motor completo de layout de navegador, isso é uma escolha de renderizador independente de qual framework chamou o motor.
Documentos relacionados
Seção intitulada “Documentos relacionados”- O guia de decisão de integração — o mapa de caso de uso para pacote, incluindo renderizadores e a superfície do serviço Connect, quando você precisa decidir em vez de padronizar.
- Open core, sem lock-in — por que o motor é o ativo e as bridges são finas, então padronizar não aprisiona você.
- O pipeline HTML — o que o motor in-process cobre, para que você saiba quando um renderizador de navegador é a questão separada.
- As fundações do PHP 8.4 — o piso de runtime que toda bridge e o caminho standalone compartilham.
Glossário
Seção intitulada “Glossário”- Motor core —
nextpdf/core, o motor de PDF 2.0 agnóstico de framework sobre o qual toda bridge e o caminho standalone se constroem. - Bridge de framework — um pacote de integração (Laravel, Symfony, CodeIgniter) que adapta o motor aos idiomas de um framework — facade, factory, resposta, job enfileirado — sem mudar suas capacidades.
- Caminho standalone — usar o motor core diretamente, sem framework,
construindo um
Documentvocê mesmo; a rota para ferramentas CLI, daemons e bibliotecas. - Documento descartável — o contrato
Documentde uso único: construir, emitir, descartar. Cada resolução de container retorna um novo, então nenhum estado vaza entre requisições em um worker de vida longa. - PAdES — PDF Advanced Electronic Signatures, a família de perfis ETSI para assinatura de PDF. A assinatura baseline (B-B e B-T) está no Core; a validação de longo prazo (B-LT e B-LTA) é uma capacidade das edições avançadas. Qualquer uma é alcançada por meio de qualquer superfície, abordada em profundidade nas páginas de assinatura.