Por que o seu motor de PDF pertence ao PHP, e não a um sidecar
Spec: ISO/IEC 25010:2023, §3.7ISO/IEC 25010:2023 §3.7Spec: ISO 32000-2, §7ISO 32000-2 §7
Visão geral
Seção intitulada “Visão geral”Há dois lugares em que um PDF pode ser feito: dentro do seu processo PHP, ou em outro lugar que você tem de operar. O NextPDF o faz por dentro. Esta página é o argumento dessa escolha — por que um motor em processo é geralmente o padrão certo, e o que o padrão do “outro lugar” de fato custa uma vez em produção.
Este é o ângulo da arquitetura, não o do framework. Como o mesmo motor alcança Laravel, Symfony, CodeIgniter e código standalone é uma história diferente, contada em one engine, every framework.
Por que isso importa
Seção intitulada “Por que isso importa”Uma funcionalidade de PDF raramente começa como um sistema que você opera. Ela começa como uma linha em um controller: renderize esta fatura, retorne aquele relatório. O padrão sidecar transforma essa linha em infraestrutura. Para desenhar o documento, você agora roda uma segunda coisa — um binário externo, um navegador headless, um microsserviço separado — e tudo o que essa segunda coisa precisa se torna problema seu também: sua versão, sua memória, seu contêiner, sua rede, seus modos de falha, sua página de plantão às 2 da manhã.
O custo é invisível na demo e inevitável em produção. Um motor de documentos que vive no seu processo não tem nada disso. A pergunta não é “um sidecar consegue fazer um PDF” — é claro que consegue. É “o que você assinou para operar para chegar lá, e você precisava disso”.
A versão resumida
Seção intitulada “A versão resumida”- Em processo significa nenhum segundo runtime. O NextPDF desenha o PDF dentro do mesmo worker PHP que tratou a requisição. Não há subprocesso para gerar, serviço para implantar, nem nada extra para manter vivo.
- Um sidecar acrescenta uma superfície operacional que você não tinha. Um navegador empacotado ou binário externo traz sua própria versão, sua própria pegada de segurança e seu próprio contêiner — tudo o que você agora aplica patches e monitora.
- As fronteiras de processo são onde as coisas dão errado. Cold starts, timeouts, encanamento interprocesso frágil e dados saindo do seu processo são modos de falha que uma chamada em processo simplesmente não tem.
- Em processo é testável e determinístico. O motor é PHP tipado que você pode testar com unit tests, mockar e raciocinar a respeito — não um renderizador opaco que você só consegue sondar rodando-o e olhando a saída.
- Um navegador de verdade ainda tem usos reais. Para renderização fiel pixel a pixel de páginas web modernas arbitrárias, um navegador headless é a ferramenta honesta — e o NextPDF pode delegar a um deliberadamente. É uma costura, não o padrão.
Como o NextPDF aborda isso
Seção intitulada “Como o NextPDF aborda isso”Coloque as duas arquiteturas lado a lado. O caminho em processo é uma chamada de função. O caminho sidecar é um sistema distribuído em miniatura — e cada seta entre suas caixas é um lugar que falha de forma independente do seu código.
- In-process: call the enginewriteHtml() or the document API runs inside the current PHP worker — no subprocess, no socket.
- In-process: receive PDF bytesThe engine returns native PDF content directly; nothing left the process.
- Sidecar: serialize and shipMarkup or a request is marshalled out of your process to a binary, browser, or remote service.
- Sidecar: cross the boundaryA process spawn or network hop — with a cold start, a timeout, and an IPC contract that can break.
- Sidecar: run a second runtimeAn external renderer with its own version, memory profile, and security surface to operate and patch.
- Sidecar: deserialize backMarshal the result back in and translate the renderer’s errors into yours.
Nenhum segundo runtime para operar. O padrão sidecar são dois sistemas
vestindo a fantasia de uma funcionalidade. Um wkhtmltopdf empacotado, um serviço
Chromium headless, um microsserviço de renderização separado — cada um é um
runtime com sua própria cadência de lançamento e seus próprios bugs. Você herda
tudo isso. O motor em processo é entregue como uma dependência do Composer; ele é
atualizado da mesma forma que toda outra biblioteca no seu composer.json, sem
daemon, imagem ou socket acrescentado à sua implantação.
Desvio de versão e uma superfície de segurança mais ampla. Um navegador empacotado é uma base de código grande e de movimentação rápida, com um fluxo constante de avisos de segurança. Fixe-o e ele apodrece; acompanhe-o e ele se agita. De qualquer forma, é toda a plataforma web de um renderizador sentada na sua cadeia de suprimentos para alimentar um documento. Um motor PHP em processo é uma biblioteca focada de código que você pode ler; sua superfície de segurança é o PHP que você já roda, não uma segunda plataforma que você agora também roda.
Os dados permanecem dentro da fronteira do seu processo. Quando você delega para fora, o conteúdo do documento — que muitas vezes é exatamente o dado sensível que um PDF existe para carregar — cruza uma fronteira. Ele é escrito em um pipe, um argumento, um arquivo temporário ou um socket de rede para um serviço. Cada um desses é um lugar para vazar, registrar por acidente ou deixar para trás. Em processo, os dados nunca deixam o worker que é seu dono. O raio de explosão é um processo, não uma frota.
Encanamento frágil, cold starts e timeouts. Chamadas interprocesso e de rede falham de maneiras que uma chamada de função não pode: o subprocesso que não iniciou, o socket que travou, o timeout que você chutou errado, o cold start sob um pico de tráfego. Cada um precisa de uma política de retry, um circuit breaker e um orçamento. Uma renderização em processo ou retorna bytes ou lança uma exceção tipada que você captura na próxima linha. Não há estado de rede parcial para reconciliar.
Observabilidade e teste ficam mais difíceis através da fronteira. Uma falha em um sidecar chega como um código de saída, uma linha de log truncada ou um 500 de um serviço que você não controla. Reproduzi-la significa reproduzir todo aquele ambiente. Um motor em processo é observável com as ferramentas que você já usa — um stack trace, um depurador, um profiler — e é testável da mesma forma que o resto do seu PHP. Essa testabilidade é uma propriedade nomeada de qualidade de software: a ISO/IEC 25010 a coloca sob manutenibilidade (Spec: ISO/IEC 25010:2023, §3.7ISO/IEC 25010:2023 §3.7), e uma biblioteca em processo a satisfaz de forma muito mais direta do que um renderizador que você só consegue exercitar lançando-o.
O PDF sobre o qual esses testes fazem asserções é uma estrutura definida, não uma caixa-preta. Um arquivo PDF tem um layout de objetos e de arquivo especificado (Spec: ISO 32000-2, §7ISO 32000-2 §7), e um motor em processo emite essa estrutura a partir de código que você pode ler — então um teste de golden-file ou estrutural confere bytes que uma função conhecida produziu, em vez da saída de um programa externo que você só consegue observar.
Exemplo prático
Seção intitulada “Exemplo prático”A questão toda cabe em um punhado de linhas. Não há cliente, base URL, health check nem política de retry — porque não há segundo sistema.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
// The engine runs inside this very process. No subprocess is spawned,// no socket is opened, and the report data never leaves the worker.$document = Document::createStandalone();$document->setTitle('Quarterly Report');$document->addPage();
$html = <<<'HTML'<h1 style="color: #1E3A8A;">Quarterly Report</h1><p>Rendered <strong>in-process</strong> by PHP — no browser, no sidecar.</p>HTML;
$document->writeHtml($html);
// PDF bytes are returned directly. There is no boundary to marshal across,// so there is no timeout, cold start, or deserialization step to handle.$bytes = $document->getPdfData();Contraste o formato da versão sidecar — não o seu código, o seu formato operacional. Ela precisa de um binário ou serviço instalado e alcançável, de uma requisição serializada e enviada, de um timeout escolhido, de um caminho de falha para quando o renderizador está frio ou fora do ar, e do resultado empacotado de volta. Nada disso está no trecho acima, porque nada disso existe quando o motor é uma biblioteca.
Equívoco comum
Seção intitulada “Equívoco comum”A suposição frequente é a de que renderização de PDF “de verdade” tem de significar um navegador, então em processo deve ser a versão de brinquedo. Isso inverte o trade-off. Um navegador é a ferramenta certa quando você precisa de renderização exata, fiel pixel a pixel, de conteúdo web moderno arbitrário. Ele é o padrão errado para o trabalho em formato de documento que a maioria das equipes de fato faz — faturas, relatórios, extratos, contratos — onde o layout é conhecido, os dados são seus e a correção é conferida por um validador, não a olho nu. Para esse trabalho, o peso operacional de um sidecar não lhe compra nada que o motor em processo já não dê, e lhe custa tudo o que está nas seções acima.
O equívoco espelhado é o que esta página tem o cuidado de não cometer: alegar que um motor em processo renderiza “toda a web” como um navegador. Ele não renderiza, e o NextPDF não finge que sim. Seu pipeline de HTML em processo é um subconjunto alinhado à especificação, focado em layout de documento, com fronteiras documentadas — o escopo honesto está exposto em the HTML pipeline. Quando você genuinamente precisa de fidelidade completa de navegador, essa é uma delegação deliberada e opt-in, não um fallback silencioso.
Limites e fronteiras
Seção intitulada “Limites e fronteiras”Em processo é o padrão certo. Não é uma alegação universal de que um subprocesso nunca se justifica. Onde um documento genuinamente exige renderização exata de CSS moderno arbitrário que o motor em processo não cobre, delegar a um navegador headless é a escolha correta — e o NextPDF apoia esse caminho deliberadamente, com seu acesso à rede restrito, como uma costura em vez do padrão. Os dois não são rivais; são ferramentas diferentes para tarefas diferentes.
Esta página argumenta a arquitetura, não uma matriz de suporte a CSS. Exatamente qual HTML e CSS o pipeline em processo cobre é definido pelo código do motor e por seus testes de conformidade, e é documentado junto com esse pipeline — não prometido aqui. “Em processo” descreve o caminho de renderização padrão; não é uma alegação de que todo caminho possível evita um subprocesso.
A superfície de capacidade permanece simples: o motor em processo é Core, e o caminho de delegação ao navegador é uma extensão opcional, independente da edição.
| Edition | Availability |
|---|---|
| Core | O Core renderiza o PDF em processo no PHP — sem subprocesso, binário ou sidecar por padrão. |
| Pro | O caminho de delegação ao navegador headless é uma extensão de complemento opcional, independente do nível de edição. |
| Enterprise | O caminho de delegação ao navegador headless é uma extensão de complemento opcional, independente do nível de edição. |
Documentos relacionados
Seção intitulada “Documentos relacionados”- The HTML pipeline — o escopo honesto do motor em processo, e exatamente quando delegar a um navegador é o certo.
- One engine, every framework — o eixo complementar: como o mesmo motor em processo alcança todos os frameworks PHP sem uma biblioteca diferente por stack.
- Operating NextPDF in production — como é, no dia a dia, rodar um motor em processo, sem nenhum runtime extra para operar.
- Memory and streaming — como o motor mantém a geração em processo limitada sob carga.
Glossário
Seção intitulada “Glossário”- Geração em processo — produzir o PDF dentro do mesmo worker PHP que trata a requisição, sem subprocesso, socket ou serviço externo.
- Sidecar — um runtime separado que roda ao lado da sua aplicação para fazer um trabalho; aqui, um binário externo, navegador headless ou microsserviço que renderiza o PDF fora do seu processo.
- Cold start — o pico de latência e de recursos incorrido quando um subprocesso ou serviço precisa ser iniciado do nada antes de poder atender à primeira requisição.
- IPC — inter-process communication: os pipes, sockets, arquivos temporários ou chamadas de rede usados para passar dados de e para um processo separado, e uma fonte recorrente de falhas frágeis e difíceis de depurar.
- Costura de delegação ao navegador — o caminho opcional, opt-in, que entrega uma renderização a um navegador headless para fidelidade exata, com acesso de rede a sub-recursos bloqueado; uma escolha deliberada, não o padrão.