Pular para o conteúdo

Migrar do Dompdf para o NextPDF

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.

Terminal window
composer require nextpdf/core:^3

Mantenha 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.

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.

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).

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.

DompdfNextPDFNotas
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 metadadosOs 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.
<?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";

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 that
is <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);
  • Sem renderização em duas fases. Código Dompdf que inspeciona o estado entre render() e output(), como ler a contagem de páginas, não tem análogo no NextPDF nesse exato limite. Em vez disso, consulte o documento após writeHtml().
  • Codificação. O NextPDF omite o parâmetro $encoding do Dompdf. Converta a entrada para UTF-8 antes de writeHtml(). 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_php do 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 de writeHtml().
  • 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.

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.

  • Sem busca remota por contexto de stream. O NextPDF não implementa o caminho de busca remota setHttpContext() / enable_remote do 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 ao enable_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.
DeclaraçãoEspecificaçãoCláusulareference_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.

Não se aplica. O Core cobre este caminho de migração HTML-para-PDF.


Detalhes da migração (seções obrigatórias R6)

Seção intitulada “Detalhes da migração (seções obrigatórias R6)”

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.

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.

Opção do Dompdf (chave / setter)NextPDFNotas
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/heightO 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->fontsDirectoryUma ú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 registradaDefina 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.
  • 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.

  • enable_php (PHP no documento) — ausente intencionalmente.
  • setHttpContext() / enable_remote busca remota — ausente intencionalmente.
  • Acesso público a FrameTree / Canvas / Stylesheet — sem análogo público.
  • dpi como 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.

  1. Adicione nextpdf/core ao lado de dompdf/dompdf. Não remova o Dompdf ainda.
  2. Escolha um documento de baixo risco. Reescreva o ponto de chamada dele com o mapeamento de verbos e exclua a chamada render().
  3. 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.
  4. Converta o uso de opções com o mapa de opções; recalcule tamanhos derivados de DPI para pontos.
  5. Pré-resolva os recursos remotos e relativos para caminhos absolutos ou data URIs para eliminar a variável de resolução.
  6. Repita por documento, do menor risco para o maior. Mantenha ambos os motores instalados até que o último ponto de chamada seja migrado.
  7. Remova dompdf/dompdf do composer.json somente após a última 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.php e pela suíte Html tests/ 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.

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 NextPDFEvidê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).

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.

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.

  • 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.