Migrar do Dompdf para o NextPDF
Visão geral
Seção intitulada “Visão geral”Este guia ajuda você a migrar uma base de código baseada em Dompdf que gera arquivos Portable Document Format (PDF) a partir de Hypertext Markup Language (HTML) para o pipeline Html do NextPDF. A maioria dos pontos de chamada pode ser migrada mecanicamente porque ambas as bibliotecas seguem o mesmo fluxo geral: carregar o HTML, renderizá-lo e emitir um PDF. O trabalho de fato está no mapa de opções e nas diferenças de suporte a Cascading Style Sheets (CSS). O NextPDF e o Dompdf são motores independentes; portanto, um layout produzido pelo Dompdf é compatível com o resultado do NextPDF, mas não é idêntico byte a byte a ele. Este guia cobre o mapeamento de verbos, o mapeamento de chaves de opção, as diferenças de comportamento e uma sequência de migração segura.
O suporte do NextPDF a um recurso HTML/CSS não garante que um documento Dompdf seja reproduzido pixel a pixel. A matriz de suporte a CSS é a autoridade para os recursos Verified. Este guia descreve o comportamento; ele não afirma equivalência visual.
Instalação
Seção intitulada “Instalação”composer require nextpdf/core:^3Mantenha o dompdf/dompdf instalado durante a transição. A sequência de migração segura executa os dois motores lado a lado até que cada ponto de chamada seja migrado. Remova-o assim que a migração estiver concluída.
Visão conceitual
Seção intitulada “Visão conceitual”O objeto Dompdf do Dompdf é uma fachada única que mantém o Document Object Model (DOM), a folha de estilos, a árvore de frames e o canvas. O NextPDF separa essas responsabilidades: um NextPDF\Core\Document mantém o modelo de páginas e a saída, e writeHtml() conduz o pipeline HTML. Não há uma fase separada de duas etapas para “renderizar e depois emitir”. writeHtml() faz o layout do conteúdo à medida que o escreve, e você emite o documento com save(), output() ou getPdfData().
O conteúdo de página que o NextPDF escreve é pintura de fluxo de conteúdo (content stream) conforme a ISO 32000-2 (ISO 32000-2 §8, iso32000_2_sec8#x1.x3.p14). A geometria de página controlada pela opção de tamanho do papel mapeia para a MediaBox do objeto de página (ISO 32000-2 §7, iso32000_2_sec7#x1.x104.p10). Esses são fundamentos do motor compartilhados por qualquer gerador conforme. O algoritmo de layout que transforma o CSS nesse conteúdo é próprio do NextPDF e difere do Dompdf; consulte Diferenças de comportamento.
Superfície da API
Seção intitulada “Superfície da API”A API Html do NextPDF está documentada na referência do módulo Html, gerada automaticamente a partir do PHPDoc. Os pontos de entrada usados abaixo são Document::createStandalone(), Document::writeHtml(string $html): static, Document::writeHtmlCell(...), Document::output(?string, OutputDestination), Document::save(string $path): void, Document::getPdfData(): string e o objeto de valor NextPDF\Core\Config (pageSize, margins, fontsDirectory).
Mapeamento de verbos da API
Seção intitulada “Mapeamento de verbos da API”Os nomes da API pública do Dompdf abaixo foram conferidos no repositório público upstream (dompdf/dompdf, master); consulte o sidecar de proveniência _source-sidecar-upstream-api.md no repositório. Nenhum texto da documentação upstream é reproduzido.
| Dompdf | NextPDF | Notas |
|---|---|---|
new Dompdf($options) | Document::createStandalone($config) | O Dompdf recebe um objeto Options; o NextPDF recebe um NextPDF\Core\Config. Use DocumentFactory para workers de longa duração em vez de createStandalone(). |
$dompdf->loadHtml($html, $encoding) | $doc->writeHtml($html) | O NextPDF trata a entrada como UTF-8. Transcodifique a entrada não-UTF-8 antes da chamada, em vez de passar um argumento de codificação. |
$dompdf->loadHtmlFile($file) | $doc->writeHtml(file_get_contents($file)) | O NextPDF não tem variante de carregamento de arquivo. Leia o arquivo você mesmo para que a política de recursos permaneça no seu código. |
$dompdf->setPaper($size, $orientation) | ConfigpageSize (um objeto de valor PageSize) | Consulte o mapa de opções. |
$dompdf->render() | (implícito) | O NextPDF faz o layout durante writeHtml(); não há fase de renderização separada. Remova a chamada render(). |
$dompdf->output() | $doc->getPdfData() | Retorna os bytes do PDF. |
$dompdf->stream($name, $opts) | $doc->output($name, OutputDestination::Download) | O NextPDF seleciona o destino com o enum OutputDestination. |
$dompdf->setBasePath($p) / setProtocol() / setBaseHost() | (a resolução de recursos difere) | O NextPDF resolve recursos relativos em relação ao conjunto de trabalho do documento, não a uma tripla base path/protocol; consulte Diferenças de comportamento. |
$dompdf->addInfo($label, $value) | $doc->setTitle() / setAuthor() / API de metadados | Os pares livres de informação do Dompdf mapeiam para setters de metadados tipados (ISO 32000-2 §14 informações do documento, iso32000_2_sec14#x1.x5.p5). |
$dompdf->setHttpContext($ctx) | (sem equivalente) | O NextPDF não busca recursos remotos por meio de um contexto de stream; consulte Não suportado / sem equivalente direto. |
Exemplo de código — Início rápido
Seção intitulada “Exemplo de código — Início rápido”<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
// Dompdf:// $dompdf = new Dompdf();// $dompdf->loadHtml('<h1>Invoice</h1>');// $dompdf->setPaper('A4', 'portrait');// $dompdf->render();// file_put_contents('out.pdf', $dompdf->output());
// NextPDF — the createStandalone() default page size is A4 portrait:$doc = Document::createStandalone();$doc->setTitle('Invoice');$doc->addPage();$doc->writeHtml('<h1>Invoice</h1>');$doc->save(__DIR__ . '/out.pdf');
echo "Wrote out.pdf\n";Exemplo de código — Produção
Seção intitulada “Exemplo de código — Produção”Isto espelha examples/08-html-basic.php, o respaldo executável deste guia, com tamanho de papel e margens explícitos, diferentes do padrão. Corresponde a uma chamada setPaper() do Dompdf mais uma configuração de margens via Options.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Contracts\OutputDestination;use NextPDF\Core\Config;use NextPDF\Core\Document;use NextPDF\ValueObjects\Margin;use NextPDF\ValueObjects\PageSize;
// Equivalent of: $dompdf->setPaper('letter','portrait') + margin options.// US Letter portrait = 612 x 792 pt.// Margin constructor order is (top, right, bottom, left) — all 0.5in here.$config = new Config( pageSize: new PageSize(612.0, 792.0, 'Letter'), margins: new Margin(36.0, 36.0, 36.0, 36.0), // top,right,bottom,left; 0.5in in points);
$doc = Document::createStandalone($config);$doc->setTitle('Quarterly Report');$doc->setAuthor('Finance');$doc->addPage();
$html = <<<'HTML'<h1 style="color:#1E3A8A;">Quarterly Report</h1><p>This report renders through the NextPDF Html pipeline. The CSS subset thatis <strong>Verified</strong> for production is the support-matrix authority,not this page.</p><table border="1"> <tr><th>Region</th><th>Total</th></tr> <tr><td>EMEA</td><td>1,204</td></tr></table>HTML;
$doc->writeHtml($html);
// Equivalent of $dompdf->stream('report.pdf'):$doc->output('report.pdf', OutputDestination::Download);Casos extremos e pegadinhas
Seção intitulada “Casos extremos e pegadinhas”- Sem renderização em duas fases. Código Dompdf que inspeciona o estado entre
render()eoutput(), como ler a contagem de páginas, não tem análogo no NextPDF nesse exato limite. Em vez disso, consulte o documento apóswriteHtml(). - Codificação. O NextPDF omite o parâmetro
$encodingdo Dompdf. Converta a entrada para UTF-8 antes dewriteHtml(). Passar bytes Latin-1 produz mojibake, não um erro. render()deixado no lugar. Uma chamada remanescente no estilo$dompdf->render()não tem método no NextPDF e falha com um erro fatal “undefined method”. Remova-a durante a migração; não a substitua por um stub.- PHP inline. O
enable_phpdo Dompdf avalia<script type="text/php">. O NextPDF não tem execução de PHP no documento por design, porque isso é uma superfície de injeção. Mova essa lógica para o seu PHP antes dewriteHtml(). - Resolução de recursos relativos. O Dompdf resolve
<img src>em relação à tripla base path/protocol/host. O NextPDF resolve em relação ao conjunto de trabalho do documento. Durante a migração, passe caminhos absolutos ou data URIs pré-resolvidas para eliminar essa variável.
Desempenho
Seção intitulada “Desempenho”writeHtml() faz o layout em uma única passagem em fluxo (streaming), conforme descrito no registro de decisão de arquitetura ADR-001. Não há objeto intermediário de árvore de frames retido após o layout; portanto, o pico de memória acompanha o tamanho do documento em vez da contagem de nós do DOM. O orçamento de desempenho para o exemplo deste guia é wall_ms: 2000, peak_mb: 128. Para documentos grandes, divida o HTML nos limites de addPage() em vez de construir uma única string de vários megabytes.
Notas de segurança
Seção intitulada “Notas de segurança”- Sem busca remota por contexto de stream. O NextPDF não implementa o caminho de busca remota
setHttpContext()/enable_remotedo Dompdf. Resolva e valide os recursos remotos na sua aplicação; depois, passe os bytes ou data URIs. Isso elimina a superfície de server-side request forgery (SSRF) associada aoenable_remote. - Sem execução de código no documento. A ausência de um equivalente a
enable_phpé uma medida deliberada de hardening, não uma lacuna. - Os metadados do documento que você define por meio dos setters tipados são gravados no dicionário de informações ISO 32000-2 §14 / Extensible Metadata Platform (XMP) (
iso32000_2_sec14#x1.x5.p5). Não coloque segredos ali.
Conformidade
Seção intitulada “Conformidade”| Declaração | Especificação | Cláusula | reference_id |
|---|---|---|---|
| O conteúdo de página é pintura de fluxo de conteúdo no modelo opaque/transparent. | ISO 32000-2 | §8 | |
| O tamanho do papel mapeia para a caixa de limites do objeto de página. | ISO 32000-2 | §7 | |
| As fontes HTML são gravadas como programas de fonte embedded/subset. | ISO 32000-2 | §9 | |
| O processamento de espaço em branco / quebra de linha é específico do motor. | CSS Text 3 | §6.5 |
O NextPDF produz conteúdo ISO 32000-2. Ele não afirma que um documento Dompdf migrado seja visualmente idêntico. Revise a saída sempre que você trocar de renderizador.
Contexto comercial
Seção intitulada “Contexto comercial”Não se aplica. O Core cobre este caminho de migração HTML-para-PDF.
Veja também
Seção intitulada “Veja também”Detalhes da migração (seções obrigatórias R6)
Seção intitulada “Detalhes da migração (seções obrigatórias R6)”Para quem é isto
Seção intitulada “Para quem é isto”Use esta página se a sua equipe executa dompdf/dompdf para HTML-para-PDF no lado do servidor e quer migrar para o motor NextPDF. Se você só chama loadHtml / setPaper / render / output, o mapeamento de verbos cobre toda a sua superfície.
Dentro do escopo: os verbos da fachada Dompdf, as chaves de Options, as expectativas de paridade de recursos CSS, a resolução de recursos e os metadados. Fora do escopo: os objetos internos FrameTree/Canvas/Stylesheet do Dompdf. O NextPDF não tem análogos públicos; portanto, não migre código que acesse esses objetos. Substitua-o pela API pública.
Mapa de compatibilidade
Seção intitulada “Mapa de compatibilidade”Cobertura significa compatibilidade comportamental, não um shim de substituição direta. O NextPDF não tem um shim de classe Dompdf (diferentemente do caminho TCPDF; consulte /migration/tcpdf-compat/). Reescreva cada ponto de chamada usando o mapeamento de verbos. As linhas Verified da matriz de suporte a CSS regem por completo as expectativas de recursos CSS. Este guia não reapresenta o status por propriedade.
Mapa de opções e configuração
Seção intitulada “Mapa de opções e configuração”| Opção do Dompdf (chave / setter) | NextPDF | Notas |
|---|---|---|
default_paper_size / setDefaultPaperSize() ; setPaper($size,...) | Config->pageSize (VO PageSize) | Tamanhos nomeados tornam-se dimensões em pontos explícitas. new PageSize(595.276, 841.890, 'A4') é o padrão de createStandalone(). |
default_paper_orientation / setDefaultPaperOrientation() | inverta PageSize width/height | O NextPDF não tem flag de orientação. Uma página em paisagem é um PageSize com largura > altura. |
dpi / setDpi() | (não é um controle global) | O NextPDF trabalha em pontos PDF (1/72 pol). O dimensionamento de imagens é por imagem, não um multiplicador de pontos por polegada (DPI) do documento. Recalcule tamanhos fixos em pixels para pontos. |
enable_remote / setIsRemoteEnabled() | (sem equivalente — por design) | Resolva os recursos remotos no seu código; consulte Notas de segurança. |
enable_html5_parser / setIsHtml5ParserEnabled() | (sempre analisa o HTML) | Sem alternância; o parser é o pipeline. |
enable_php / setIsPhpEnabled() | (sem equivalente — por design) | PHP no documento não é suportado. Mova a lógica para fora do template. |
font_dir / setFontDir() | Config->fontsDirectory | Uma única string de diretório de fontes. |
chroot | (resolva na aplicação) | O NextPDF não aceita uma opção de isolamento do sistema de arquivos. Valide os caminhos antes de passar os bytes. |
default_font / setDefaultFont() | CSS font-family / fonte registrada | Defina o padrão na sua folha de estilos base ou no registro de fontes, não em uma opção global. |
enable_font_subsetting / setIsFontSubsettingEnabled() | (sempre faz subset) | O NextPDF sempre faz subset das fontes incorporadas (ISO 32000-2 §9, iso32000_2_sec9#x1.x45.p7). Não existe “desligado”; um fluxo Dompdf com a flag desligada não tem equivalente e não é necessário. |
Diferenças de comportamento
Seção intitulada “Diferenças de comportamento”- Motor de layout. O Dompdf e o NextPDF usam implementações de layout CSS independentes. O colapso de espaço em branco e a quebra de linha são especificados, mas continuam dependentes do motor (CSS Text 3 §6.5,
css_text_3#x1.x6.x5.p20). Espere diferenças de quebra de linha e de paginação em texto denso. Atualize a baseline dos diffs visuais após a migração. - Costura de renderização. Sem limite em duas fases
render()/output()(consulte Casos extremos). - Resolução de recursos. O tratamento de base-path/protocol/host difere do conjunto de trabalho do documento.
- Modelo de DPI. Os pontos PDF diferem do multiplicador de DPI do Dompdf.
- Metadados. Os pares livres de
addInfo()diferem dos setters tipados (ISO 32000-2 §14,iso32000_2_sec14#x1.x5.p5).
Essas são diferenças de comportamento documentadas, não defeitos de nenhum dos motores.
Não suportado / sem equivalente direto
Seção intitulada “Não suportado / sem equivalente direto”enable_php(PHP no documento) — ausente intencionalmente.setHttpContext()/enable_remotebusca remota — ausente intencionalmente.- Acesso público a
FrameTree/Canvas/Stylesheet— sem análogo público. dpicomo multiplicador global do documento — não modelado.
Código que depende disso não “migra”. Remova-o ou reformule-o em código de aplicação usando as linhas acima.
Sequência de migração segura
Seção intitulada “Sequência de migração segura”- Adicione
nextpdf/coreao lado dedompdf/dompdf. Não remova o Dompdf ainda. - Escolha um documento de baixo risco. Reescreva o ponto de chamada dele com o mapeamento de verbos e exclua a chamada
render(). - Gere ambos os PDFs a partir da mesma entrada e compare-os visualmente (diff). Trate as diferenças como esperadas, porque os motores são independentes, e decida a aceitação documento a documento.
- Converta o uso de opções com o mapa de opções; recalcule tamanhos derivados de DPI para pontos.
- Pré-resolva os recursos remotos e relativos para caminhos absolutos ou data URIs para eliminar a variável de resolução.
- Repita por documento, do menor risco para o maior. Mantenha ambos os motores instalados até que o último ponto de chamada seja migrado.
- Remova
dompdf/dompdfdocomposer.jsonsomente após a última migração.
Testando a migração
Seção intitulada “Testando a migração”- Capture um snapshot da saída Dompdf de documentos representativos antes de alterar o código. Use entradas golden, não bytes golden, porque os bytes serão diferentes.
- Para cada documento migrado, submeta a saída do NextPDF à sua própria verificação de aceitação, como diff visual ou asserções de extração de texto. O próprio comportamento do pipeline HTML do NextPDF é coberto por
examples/08-html-basic.phpe pela suíte Htmltests/do core. A aceitação da migração é específica de cada documento, e você é responsável por confirmá-la. - Adicione um teste de regressão para cada documento migrado para que uma futura atualização do motor seja detectada.
Evidência / rastreabilidade
Seção intitulada “Evidência / rastreabilidade”Toda declaração de comportamento do NextPDF nesta página é sustentada por um teste no repositório, exemplo, assinatura de fonte ou registro de decisão de arquitetura (ADR), ou, para propriedades de formato PDF, pelas cláusulas ISO 32000-2 / CSS fixadas via Retrieval-Augmented Generation (RAG) no citations: do frontmatter e pela tabela Conformidade. O comportamento do Dompdf é afirmado apenas como “motor independente — espere diferenças documentadas”. Esta página não afirma nenhuma paridade a menos que um artefato no repositório a comprove.
| Declaração de comportamento do NextPDF | Evidência no repositório (caminho) |
|---|---|
createStandalone() tem página padrão A4 retrato (595.276 × 841.890 pt). | src/Core/Config.php (padrão PageSize(595.276, 841.890, 'A4')); tests/Unit/Core/DocumentCreateStandaloneAndConfigWithersEdgeCaseTest.php (createStandaloneWithNullConfigBuildsDocumentWithA4Defaults). |
writeHtml() faz o layout em uma única passagem em fluxo; sem DOM retido após o layout. | docs/architecture/adr/ADR-001-stream-based-rendering-pipeline.md; src/Core/Concerns/HasTextOutput.php (writeHtml()). |
writeHtml() cria automaticamente a primeira página quando nenhuma existe. | tests/Unit/Core/Concerns/DocumentTextOutputFontSubsettingAndBorderEdgeCaseTest.php (writeHtmlAutoCreatesFirstPageWhenNoPagesExist). |
output() / save() / getPdfData() são os verbos de emissão (sem duas fases render/output). | src/Core/Concerns/HasOutput.php (output(), save(), getPdfData()); tests/Unit/Core/Concerns/DocumentOutputDestinationDispatchTest.php. |
O destino de saída é o enum NextPDF\Contracts\OutputDestination (Inline/Download/File/String). | src/Contracts/OutputDestination.php; tests/Unit/Core/Concerns/DocumentOutputDestinationDispatchTest.php. |
| As fontes HTML são sempre gravadas como programas embedded/subset. | tests/Unit/Core/Concerns/DocumentTextOutputFontSubsettingAndBorderEdgeCaseTest.php (recordUsedCharactersAffectsFontSubsetting); ISO 32000-2 §9 (citations: do frontmatter). |
Setters de metadados tipados (setTitle/setAuthor) substituem o addInfo() de formato livre. | src/Core/Concerns/HasMetadata.php (setTitle(), setAuthor()); tests/Unit/Core/Concerns/DocumentInfoMetadataSetterBaselineTest.php. |
| Pipeline HTML ponta a ponta (o respaldo executável deste guia). | examples/08-html-basic.php; suíte tests/Unit/Html/ do core. |
| O espaço em branco / quebra de linha é específico do motor (delta de layout). | CSS Text 3 §6.5 (citations: do frontmatter + Conformidade). |
Reversão
Seção intitulada “Reversão”Como ambos os pacotes permanecem instalados até a migração final, a reversão de um ponto de chamada não convertido significa reverter esse ponto de chamada para o caminho Dompdf. Após a migração final, a reversão significa restaurar dompdf/dompdf e o ponto de chamada anterior a partir do controle de versão. Nenhuma migração de dados está envolvida; apenas mudanças de código.
Considerações de desempenho
Seção intitulada “Considerações de desempenho”Consulte Desempenho. O modelo de passagem única significa que a migração não introduz custo de retenção de árvore de frames. A principal mudança de custo por documento é a resolução antecipada de recursos do passo 5, que você pode armazenar em cache.
Pegadinhas comuns
Seção intitulada “Pegadinhas comuns”- Deixar
render()no lugar, o que causa um erro fatal de método indefinido. - Passar bytes não-UTF-8 após eliminar
$encoding, o que causa mojibake silencioso. - Esperar saída idêntica byte a byte ou pixel a pixel de motores independentes. Este guia nunca afirma substituição direta ou 100% de compatibilidade.
- Depender de templates
enable_php, que precisam ser refatorados para fora. - Tratar a matriz de suporte a CSS como consultiva. Ela é a autoridade de recursos Verified sobre o que esperar.