O modelo de pipeline
Spec: ISO 32000-2, §7.5 ISO 32000-2 §7.5 Evidence: Code-backed
Visão geral
Seção intitulada “Visão geral”Um documento do NextPDF não é produzido em uma única etapa opaca. Ele percorre um pequeno número de estágios explícitos: uma fachada que registra a intenção, uma camada de conteúdo que transforma a intenção em um modelo e um escritor que serializa esse modelo em um PDF em conformidade. Esta página explica esse formato e por que ele é o formato certo para o motor.
Por que isso importa
Seção intitulada “Por que isso importa”O próprio formato de arquivo PDF é uma estrutura em camadas — um cabeçalho, um corpo de objetos, uma tabela de referência cruzada e um trailer — e um escritor precisa montar tudo isso de forma consistente. Se o motor que o constrói for um único procedimento emaranhado, cada mudança colocará toda saída em risco. A única forma de ganhar confiança passa a ser renderizar documentos inteiros e inspecioná-los a olho, o que é lento, tardio e pouco convincente.
Um pipeline explícito inverte essa situação. Cada estágio tem uma única tarefa e um limite tipado, de modo que você pode raciocinar sobre uma mudança e testá-la no estágio que ela afeta, não apenas no final do arquivo. A arquitetura é, antes de tudo, uma decisão de testabilidade e extensibilidade.
A versão curta
Seção intitulada “A versão curta”- O ponto de entrada público é uma fachada Document. Ela é um construtor fluente, de uso único e seguro para workers, que registra o que você quer, não como isso é serializado.
- A fachada delega a cerca de duas dúzias de traits de responsabilidade focados (saída de texto, desenho, páginas, segurança, navegação e assim por diante) — cada um com uma responsabilidade, em vez de uma única classe gigante.
- O conteúdo chega por um de dois caminhos: desenho direto (primitivas gráficas) ou o motor HTML/CSS. Ambos produzem o mesmo modelo de documento interno.
- Um escritor de PDF dedicado serializa esse modelo, escolhendo uma estratégia para PDF 1.4 / 1.7 / 2.0. A produção de uma estrutura de arquivo válida fica aqui e em nenhum outro lugar.
- O estado de vida longa (os registros de fontes e imagens) tem escopo de processo e é compartilhado; o estado por requisição (o documento) é criado do zero e nunca reutilizado. O limite é explícito, e é isso que torna os runtimes de worker seguros.
Como o NextPDF aborda isso
Seção intitulada “Como o NextPDF aborda isso”A maneira mais clara de enxergar o modelo é acompanhar um documento da chamada até os bytes.
- Document facade Fluent, use-once builder; records intent via concern traits.
- Content production Direct drawing or the HTML/CSS engine — both build one document model.
- Document model Accumulated pages, content, and resources held as typed state.
- PDF writer Serialises the model; selects a PDF 1.4 / 1.7 / 2.0 strategy.
- Conforming PDF Header, object body, cross-reference table, trailer.
Duas escolhas de projeto fazem disso mais do que um diagrama.
A fachada é composta, não monolítica. O Document não implementa cada recurso por conta própria; ele delega cada área a um trait de responsabilidade dedicado — saída de texto, desenho, páginas, segurança, tipografia, navegação, transações e assim por diante. Um novo método de documento pertence ao trait responsável por sua área, não à própria fachada. A classe que você chama continua pequena, e as responsabilidades continuam separadas.
O escritor é dono exclusivo da estrutura de arquivo. A produção de conteúdo decide quais marcas e objetos existem; o escritor decide como eles se tornam um arquivo PDF válido, inclusive qual estratégia de versão se aplica. Essa separação é imposta como uma regra arquitetural: o código de layout e de conteúdo não emite a estrutura final do arquivo, e o escritor não toma decisões de layout. O benefício é que “a saída é um PDF válido?” tem exatamente um lugar para ser testado.
O limite de tempo de vida faz parte do modelo, não é uma reflexão tardia. Os registros de fontes e imagens vivem durante toda a vida do processo e são compartilhados entre requisições; o documento, seu contexto de renderização e o escritor são criados por requisição e descartados. Em um runtime de worker, essa distinção é a diferença entre reutilização segura e corrupção entre requisições. Por isso, ela é declarada na arquitetura, não deixada à disciplina.
O que as evidências dizem
Seção intitulada “O que as evidências dizem”Esta página é Evidence: Code-backed . Os estágios mapeiam para a estrutura real no repositório do core:
- A fachada e sua delegação estão em
src/Core/Document.php, junto com os traits de responsabilidade emsrc/Core/Concerns/(saída de texto, saída, desenho, páginas, segurança, tipografia, navegação, transações e mais — cada um com uma única responsabilidade). - Os dois caminhos de conteúdo são o motor HTML/CSS (
src/Html/) e o desenho direto (src/Graphics/), ambos alimentando o modelo interno. - A serialização e a estratégia de versão do PDF vivem em
src/Writer/(PdfWriter.php, com classes de estratégia explícitas para PDF 1.4 / 1.7 / 2.0). - O limite entre tempo de vida do processo e por requisição é o desenho seguro para workers registrado na visão geral da arquitetura e exercitado pelo exemplo de worker-factory que acompanha o produto, que compartilha um
FontRegistrye umImageRegistryentre requisições enquanto cria cadaDocumentdo zero.
O destino é fixado pelo formato. A saída do escritor precisa ser um cabeçalho, um corpo de objetos, uma tabela de referência cruzada e um trailer, conforme Spec: ISO 32000-2, §7.5 ISO 32000-2 §7.5 . Concentrar essa obrigação em um único estágio é o que permite que o resto do motor permaneça focado no conteúdo, em vez da montagem da estrutura de arquivo.
Exemplo prático
Seção intitulada “Exemplo prático”A tarefa da fachada é fazer a intenção parecer intenção. O caminho de conteúdo e o escritor permanecem invisíveis no ponto de chamada:
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone(); // facade$doc->setTitle('Quarterly Report'); // metadata concern$doc->addPage(); // pages concern$doc->setFont('helvetica', 'B', 16); // typography concern$doc->cell(0, 12, 'Summary', newLine: true); // text-output concern$doc->writeHtml('<p>Generated in-process.</p>'); // HTML content path$doc->save(__DIR__ . '/report.pdf'); // writer stageCada chamada cai em uma responsabilidade diferente. Dois caminhos de conteúdo diferentes alimentam o mesmo modelo. Exatamente um estágio — save() — transforma o modelo em bytes de arquivo. Nada no ponto de chamada precisa saber como a tabela de referência cruzada é construída.
Equívoco comum
Seção intitulada “Equívoco comum”A leitura equivocada mais comum é achar que “pipeline” implica uma API de streaming por push, conectada estágio a estágio, como um pipe do Unix. Não é o caso. Aqui, o pipeline é uma decomposição arquitetural: estágios com responsabilidades únicas e limites tipados. Você continua programando contra uma fachada fluente. Os estágios são a forma como o motor é construído e testado, não um transporte que você monta à mão.
Um erro relacionado é supor que a fachada é o motor. Ela é o ponto de entrada. O trabalho real é distribuído entre os traits de responsabilidade, os dois caminhos de conteúdo e um escritor. Essa distribuição é justamente o motivo pelo qual a mudança de um recurso não põe toda saída em risco.
Limites e fronteiras
Seção intitulada “Limites e fronteiras”Esta página descreve o formato do pipeline, não a API interna de qualquer estágio isolado. O inventário exato de traits de responsabilidade, as regras de seleção da estratégia do escritor e os campos do modelo de conteúdo são definidos pelo código e pela referência, não por esta explicação. A contagem exata de traits é um detalhe de implementação que pode mudar sem mudar o modelo. Esta página não cobre os estágios internos do motor HTML (um tópico à parte) nem o comportamento de streaming e de memória do escritor (também à parte). As afirmações estruturais são precisas na data de revisão desta página; a fonte autoritativa é o src/Core/, src/Html/, src/Graphics/ e src/Writer/ do repositório do core.
O modelo de pipeline é idêntico entre todas as edições; as edições adicionam capacidades dentro dos estágios, não novos estágios:
| Edition | Availability |
|---|---|
| Core | O Core implementa o pipeline completo de fachada → conteúdo → escritor. |
| Pro | O Pro adiciona capacidades dentro dos estágios existentes, não novos estágios. |
| Enterprise | O Enterprise adiciona capacidades dentro dos estágios existentes, não novos estágios. |
Documentos relacionados
Seção intitulada “Documentos relacionados”- Memória e streaming — como o estágio do escritor mantém a memória limitada.
- O pipeline HTML — os estágios internos do caminho de conteúdo HTML.
- Tipos estritos, em todos os lugares — os limites tipados que tornam cada estágio testável de forma independente.
Glossário
Seção intitulada “Glossário”- Fachada — o ponto de entrada público
Document: um construtor fluente, de uso único, que registra a intenção e delega aos traits de responsabilidade. - Trait de responsabilidade — um trait PHP focado que a fachada compõe, cada um dono de uma única área de recurso (saída de texto, desenho, páginas, segurança e assim por diante).
- Caminho de conteúdo — uma das duas maneiras pelas quais o conteúdo entra no modelo: desenho direto ou o motor HTML/CSS.
- Modelo de documento — o acúmulo interno e tipado do motor de páginas, conteúdo e recursos antes da serialização.
- Estágio do escritor — o componente que serializa o modelo em um PDF válido, selecionando uma estratégia para PDF 1.4 / 1.7 / 2.0.
- Seguro para workers — projetado para que o estado de tempo de vida do processo seja compartilhado com segurança, enquanto o estado por requisição é criado do zero e nunca reutilizado.