Pular para o conteúdo
getnextpdf.com

Migração do FPDF para o NextPDF

Este guia ajuda você a migrar uma base de código baseada em FPDF para o núcleo do NextPDF. O FPDF é uma das bibliotecas legadas de Portable Document Format (PDF) em PHP mais amplamente implantadas, e sua superfície de desenho — AddPage, SetFont, Cell, MultiCell, Write, Text, Image, Output guiados por um cursor x/y manual — mapeia de forma limpa para a própria API de cell/text do NextPDF, porque os métodos de desenho de baixo nível do NextPDF seguem a mesma linhagem FPDF/TCPDF. O NextPDF não é um clone drop-in do FPDF, no entanto: ele é um mecanismo PDF 2.0 moderno com tipos estritos, subdivisão (subset) de fontes, assinatura, PDF/A e acessibilidade (tagged PDF). As duas mudanças reais são o modelo de unidade (o NextPDF trabalha em pontos PDF; o FPDF usa milímetros por padrão) e os verbos de saída (um enum tipado OutputDestination em vez dos caracteres 'I'/'D'/'F'/'S' do FPDF).

Não há um shim de classe FPDF no núcleo. Reescreva cada local de chamada usando o mapeamento de verbos. Se você quer a menor mudança inicial para uma base de código TCPDF 6.x em vez disso, consulte o adaptador de compatibilidade do TCPDF, que oferece um caminho drop-in quase compatível com a origem; o FPDF não tem um adaptador desses.

Terminal window
composer require nextpdf/core:^3

Mantenha setasign/fpdf (ou o seu fpdf/fpdf) instalado enquanto você faz a migração. Remova-o após a transição final (consulte sequência de migração segura).

O FPDF e o NextPDF compartilham o mesmo modelo mental: um documento feito de páginas, um cursor (a posição x/y atual) e verbos que desenham na posição do cursor ou a avançam. SetXY, Cell, Ln e MultiCell, todos leem e mutam o cursor em ambas as bibliotecas, então a maior parte do código FPDF procedural se traduz linha por linha.

As diferenças são deliberadas, não acidentais:

  • Unidades. O construtor do FPDF (new FPDF($orientation, $unit, $size)) usa milímetros por padrão. O NextPDF trabalha em pontos PDF (1 pt = 1/72 pol, ISO 32000-2 §7). Não há um botão de unidade para o documento inteiro — converta mm para pontos uma vez (pt = mm * 72 / 25.4).
  • A direção Y permanece a mesma para você. Como o FPDF, as coordenadas de usuário do NextPDF colocam y = 0 no topo da página e aumentam para baixo, então a aritmética do cursor é portada diretamente. O NextPDF converte para a origem PDF-nativa no canto inferior esquerdo internamente.
  • A construção é explícita. O FPDF dobra orientation, unit e size dentro do construtor; o NextPDF recebe um objeto de valor imutável NextPDF\Core\Config (tamanho de página, margens, diretório de fontes) e um addPage() explícito.
  • Sempre Unicode, sempre subset. O build core do FPDF é Latin-1 e precisa da variante tFPDF/UTF-8 para Unicode. O NextPDF é UTF-8 por completo e sempre incorpora fontes como programas de subset (ISO 32000-2 §9). Os arquivos de AddFont/métrica de fonte do FPDF não têm análogo; registre um diretório de fontes TrueType/OpenType e selecione a família pelo nome.

Os pontos de entrada core usados abaixo são Document::createStandalone(), Document::addPage(), Document::setFont(), Document::cell(), Document::multiCell(), Document::text(), Document::write(), Document::ln(), Document::image(), os acessadores de cursor (setXY/setX/ setY/getX/getY), Document::output(?string, OutputDestination), Document::save(string $path): void, Document::getPdfData(): string e o objeto de valor NextPDF\Core\Config. A referência completa para esses métodos core de desenho, texto e saída vive nos módulos core e no índice de referência, gerados automaticamente a partir do PHPDoc. O módulo Html é leitura relacionada para HTML-para-PDF, não a referência para os verbos desta página.

Os nomes dos métodos públicos do FPDF são de longa data e bem conhecidos. A coluna do NextPDF abaixo foi confirmada contra as assinaturas do código-fonte core (consulte Evidências / rastreabilidade).

FPDFNextPDFNotas
new FPDF($orient, $unit, $size)Document::createStandalone($config)Os argumentos de construtor orientation/unit/size tornam-se um NextPDF\Core\Config (pageSize, margins, fontsDirectory). Sem $unit — trabalhe em pontos. A página padrão de createStandalone() é A4 retrato.
$pdf->AddPage($orient, $size)$doc->addPage($size, $orientation)Mapeamento direto. $size é um objeto de valor PageSize; $orientation é o enum Orientation (Portrait/Landscape).
$pdf->SetFont($family, $style, $size)$doc->setFont($family, $style, $size)Mapeamento direto. $style usa os mesmos códigos ''/'B'/'I'/'BI' (mais 'U' para sublinhado).
$pdf->Cell($w, $h, $txt, $border, $ln, $align, $fill)$doc->cell($w, $h, $txt, $border, $newLine, $align, $fill)Mapeamento direto. $align é o enum Alignment (Left/Center/Right/Justify); $border aceita bool ou uma string 'LTRB'; $ln torna-se o bool $newLine.
$pdf->MultiCell($w, $h, $txt, $border, $align, $fill)$doc->multiCell($w, $h, $txt, $border, $align)Quebra de palavras com base nas métricas reais da fonte. Sem argumento $fill; pinte um rect() preenchido primeiro se você precisar de um fundo.
$pdf->Write($h, $txt, $link)$doc->write($h, $txt, $link)Texto fluindo a partir do cursor; $link anexa uma anotação de link de URL.
$pdf->Text($x, $y, $txt)$doc->text($x, $y, $txt)Texto em posição absoluta. Mapeamento direto.
$pdf->Ln($h)$doc->ln($h)Quebra de linha até a margem esquerda; 0 = altura de linha padrão.
$pdf->Image($file, $x, $y, $w, $h)$doc->image($file, $x, $y, $w, $h)Mapeamento direto; $x/$y/$w/$h são anuláveis (null = cursor atual / tamanho intrínseco).
$pdf->SetXY($x, $y) / SetX / SetY$doc->setXY($x, $y) / setX / setYMapeamento direto. getX()/getY() leem o cursor.
$pdf->SetMargins($l, $t, $r)$doc->setMargins(new Margin($t, $r, $bottom, $l))Um objeto de valor Margin; a ordem do construtor é (top, right, bottom, left)não o (left, top, right) do FPDF. O SetMargins do FPDF não tem argumento de baixo (sua margem inferior vem de SetAutoPageBreak($auto, $margin)), então escolha $bottom você mesmo — comumente igual à margem superior, ou passe a margem de quebra automática de página.
$pdf->SetAutoPageBreak($auto, $margin)$doc->setAutoPageBreak($auto, $margin)Mapeamento direto.
$pdf->SetDrawColor / SetFillColor / SetTextColor$doc->setDrawColor / setFillColor / setTextColorRGB (r, g, b), ou um único valor para escala de cinza.
$pdf->Line / Rect / SetLineWidth$doc->line / rect / setLineWidthMapeamento direto. rect() recebe uma string de estilo ('S'/'F'/'DF').
$pdf->SetTitle/SetAuthor/SetSubject/SetKeywords/SetCreator$doc->setTitle/setAuthor/setSubject/setKeywords/setCreatorMapeamento direto. Cai no dicionário de informações §14 / Extensible Metadata Platform (XMP) da ISO 32000-2.
$pdf->Output($dest, $name)$doc->output($name, OutputDestination::…)Os caracteres de destino do FPDF (I/D/F/S) mapeiam para o enum OutputDestination; observe que a ordem dos argumentos se inverte (nome primeiro no NextPDF).
$pdf->Output('S')$doc->getPdfData()Retorna os bytes do PDF.
$pdf->Output('F', $path)$doc->save($path)Escreve em um caminho de arquivo.
$pdf->GetStringWidth($s)(sem método público)A largura da string é calculada internamente durante a quebra de cell()/multiCell(); não há verbo público de medição por string. Conduza a quebra por meio de multiCell() em vez de medir manualmente.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Contracts\Alignment;
use NextPDF\Core\Document;
// FPDF:
// $pdf = new FPDF(); // mm, A4 portrait
// $pdf->AddPage();
// $pdf->SetFont('Arial', 'B', 16);
// $pdf->Cell(40, 10, 'Invoice');
// $pdf->Output('F', 'out.pdf');
// NextPDF — points, default page is A4 portrait:
$doc = Document::createStandalone();
$doc->setTitle('Invoice');
$doc->addPage();
$doc->setFont('Helvetica', 'B', 16.0);
$doc->cell(113.4, 28.3, 'Invoice', false, true, Alignment::Left); // ~40mm x ~10mm in points
$doc->save(__DIR__ . '/out.pdf');
echo "Wrote out.pdf\n";

Este exemplo está alinhado com examples/04-text-and-fonts.php. Ele usa um tamanho de página explícito, margens, um diretório de fontes registrado e o modelo de cell guiado por cursor que uma base de código FPDF já usa.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Contracts\Alignment;
use NextPDF\Contracts\OutputDestination;
use NextPDF\Core\Config;
use NextPDF\Core\Document;
use NextPDF\ValueObjects\Margin;
use NextPDF\ValueObjects\PageSize;
// Equivalent of: new FPDF('P', 'mm', 'A4') + SetMargins(20, 16, 20)
// i.e. FPDF left=20mm, top=16mm, right=20mm. FPDF SetMargins has no bottom
// argument, so we pick bottom = top = 16mm. Convert each mm to points
// (pt = mm * 72 / 25.4): 16mm = 45.354pt, 20mm = 56.693pt.
// Margin constructor order is (top, right, bottom, left) — NOT FPDF's (L, T, R).
$config = new Config(
pageSize: new PageSize(595.276, 841.890, 'A4'),
margins: new Margin(45.354, 56.693, 45.354, 56.693), // top,right,bottom,left in points
fontsDirectory: __DIR__ . '/fonts',
);
$doc = Document::createStandalone($config);
$doc->setTitle('Quarterly Report');
$doc->setAuthor('Finance');
$doc->addPage();
// SetFont + Cell, the FPDF way — but in points and with a real Unicode font.
$doc->setFont('DejaVuSans', 'B', 18.0);
$doc->setTextColor(30, 58, 138);
$doc->cell(0, 24.0, 'Quarterly Report', false, true, Alignment::Left);
$doc->setFont('DejaVuSans', '', 11.0);
$doc->setTextColor(0, 0, 0);
$doc->multiCell(0, 16.0, "Body text wraps on real font metrics. Unicode is "
. "native, so accented and non-Latin characters need no tFPDF variant — "
. "register the family in the fonts directory and select it by name.");
// Equivalent of $pdf->Output('D', 'report.pdf'):
$doc->output('report.pdf', OutputDestination::Download);
  • Unidades. Toda coordenada numérica, largura, altura e margem que você copia do FPDF está em milímetros por padrão. Multiplique por 72 / 25.4 para obter pontos, uma vez, durante a portagem. Misturar os dois redimensiona tudo silenciosamente de forma errada.
  • Ordem dos argumentos de Output(). O FPDF é Output($dest, $name); o NextPDF é output($name, $dest). O destino é o enum OutputDestination, não um caractere. Prefira save() / getPdfData() para saída em arquivo / string.
  • Ordem de SetMargins. O FPDF é (left, top, right); o objeto de valor Margin do NextPDF é (top, right, bottom, left). Reordene, não transcreva.
  • Fontes. O AddFont() + arquivos de métrica .php do FPDF não têm equivalente. Coloque o arquivo TrueType/OpenType no diretório de fontes e chame setFont() com o nome da família. Os nomes Base14 do Core (Helvetica, Times, Courier) resolvem sem um arquivo; sob PDF/A ou tagged PDF eles são auto-substituídos por uma fonte incorporável.
  • GetStringWidth. Não há método público de medição de string. Se seu código FPDF mede strings para dispor colunas manualmente, troque esse bloco por multiCell() (que quebra com base em métricas) ou chamadas de cell() de largura fixa.

O NextPDF emite conteúdo em uma única passagem de streaming (registro de decisão de arquitetura ADR-001); o pico de memória acompanha o tamanho do documento, não uma árvore de objetos retida. O orçamento para o exemplo deste guia é wall_ms: 2000, peak_mb: 128. Para documentos longos, conduza o conteúdo ao longo de chamadas addPage() — o mesmo formato de loop que um relatório FPDF já usa.

  • Metadados. SetTitle()/SetAuthor() mapeiam para setters tipados que escrevem o dicionário de informações §14 / XMP da ISO 32000-2. Nunca armazene segredos ali.
  • Caminhos de imagem. image() rejeita esquemas de stream-wrapper e bytes NUL incorporados antes de ler. Passe caminhos controlados pela aplicação.
  • Sem código no documento. O NextPDF não executa scripts internos do documento; nada no FPDF muda isso.
DeclaraçãoEspecificaçãoCláusula
format/orientation da página mapeiam para a caixa delimitadora da página.ISO 32000-2§7
As fontes são escritas como programas de fonte embedded/subset.ISO 32000-2§9
Título / metadados caem no dicionário de informações / XMP.ISO 32000-2§14
Linhas, retângulos e imagens são pintura no content stream.ISO 32000-2§8

O NextPDF produz conteúdo ISO 32000-2; ele não declara identidade visual com o FPDF. Reavalie a saída sempre que você trocar de renderizador.

Não se aplica. O núcleo do NextPDF cobre o caminho de migração do FPDF descrito aqui.


Equipes que executam FPDF (ou tFPDF) para geração de PDF procedural no lado do servidor. Se o seu código é uma sequência de chamadas AddPage / SetFont / Cell / MultiCell / Image / Output guiada por SetXY e Ln, o mapeamento de verbos cobre toda a sua superfície.

No escopo: os verbos de desenho do FPDF, o modelo de cursor, fontes, cores, linhas e retângulos, metadados e saída. Fora do escopo: o ferramental de arquivos de métrica AddFont do FPDF e as extensões de script FPDF de terceiros (barcodes, rotação, bookmarks) — mapeie-os para os módulos correspondentes do NextPDF (Barcode, Transforms, Navigation), que não são abordados aqui.

Compatibilidade comportamental, não um shim drop-in: o núcleo não fornece um shim de classe FPDF. Reescreva cada local de chamada. Os verbos se alinham de perto porque a API de cell/text do NextPDF compartilha a linhagem FPDF/TCPDF, mas o modelo de unidade, a ordem dos argumentos de Output e os tipos Margin/enum diferem — então uma transcrição está errada, uma tradução está certa.

construto do FPDFNextPDFNotas
$unit ('mm' padrão)(sem equivalente)Trabalhe em pontos PDF. Converta as dimensões com pt = mm * 72 / 25.4 uma vez durante a portagem.
$orientation ('P'/'L')enum Orientation em addPage(), ou troque width/height do PageSizePaisagem = largura > altura.
$size ('A4', [w,h])Config->pageSize (objeto de valor PageSize)Os formatos nomeados tornam-se dimensões explícitas em pontos; as factories PageSize::A4()A0() e Letter/Legal existem.
SetMargins($l, $t, $r)Config->margins (VO Margin)Ordem do construtor (top, right, bottom, left).
AddFont($family, $style, $file)diretório de fontes + setFont() por nomeDescarte o arquivo de métrica; coloque o TTF/OTF em Config->fontsDirectory.
  • Diretórios de fontes. O registro AddFont por fonte do FPDF colapsa para um diretório de fontes mais a correspondência de família por setFont(). Comece com Config->fontsDirectory (o caminho de busca padrão); registre diretórios adicionais via FontRegistry::addFontDirectory() ou Document::addFontDirectory() quando as fontes vivem em mais de um lugar.
  • Sempre Unicode. Sem padrão Latin-1 e sem build tFPDF separado; entrada UTF-8 é a norma.
  • Sempre subset. O NextPDF sempre subdivide as fontes incorporadas (ISO 32000-2 §9); as escolhas de incorporação de fonte do FPDF não têm equivalente e não são necessárias.
  • Refaça a baseline dos glifos. A correspondência e o fallback de fontes são específicos do mecanismo; um alias de fonte do FPDF pode precisar de um nome de família exato. Diferenças de substituição são esperadas, não são defeitos.
  • Conversão de unidade (mm → pt) — o erro de portagem mais comum; veja acima.
  • A ordem dos argumentos de Output se inverte e o destino torna-se um enum.
  • Margin / Alignment / Orientation são objetos/enums tipados, não caracteres ou triplas posicionais (l, t, r).
  • Sem GetStringWidth público — conduza a quebra por meio de multiCell().
  • Rasterização independente — a quebra de linha e a paginação em conteúdo denso podem diferir; refaça a baseline das comparações visuais.

Essas são diferenças de comportamento documentadas, não defeitos em nenhum dos mecanismos.

  • Seletor $unit do FPDF — não modelado (sempre pontos).
  • AddFont() + arquivos de métrica .php/.z — substituídos por um diretório de fontes.
  • GetStringWidth() — sem verbo público de medição de string.
  • Os caracteres de destino 'I'/'D'/'F'/'S' do FPDF — substituídos pelo enum OutputDestination + save()/getPdfData().

Código que depende destes não “migra” literalmente. Reexpresse-o com as linhas acima.

  1. Adicione nextpdf/core ao lado do FPDF; mantenha o FPDF instalado por enquanto.
  2. Escolha um documento de baixo risco. Converta o construtor por meio do mapa de unidades, e então porte cada verbo com o mapa de verbos. Converta cada coordenada em mm para pontos.
  3. Coloque as fontes do documento em Config->fontsDirectory e selecione-as pelo nome da família; descarte as chamadas AddFont.
  4. Gere ambos os PDFs para a mesma entrada e compare-os visualmente. Diferenças (substituição de fontes, quebra de linha) são esperadas em mecanismos independentes — aceite-as por documento.
  5. Substitua qualquer disposição manual baseada em GetStringWidth por multiCell() ou chamadas de cell() de largura fixa.
  6. Repita por documento, do menor risco primeiro; mantenha o FPDF instalado até a última transição.
  7. Remova o FPDF do composer.json após a transição final.
  • Capture a saída do FPDF para documentos representativos antes de alterar o código (entradas golden; os bytes serão diferentes).
  • Para cada documento migrado, valide a aceitação com a sua própria verificação (comparação visual + extração de texto). O comportamento de cell/font do NextPDF é exercitado por examples/04-text-and-fonts.php mais as suítes Font e text-output do tests/ do núcleo. A aceitação da migração é específica de cada documento e permanece sob a sua responsabilidade.
  • Adicione um teste de regressão por documento migrado.

Cada afirmação de comportamento do NextPDF nesta página é respaldada por uma assinatura de código-fonte no repositório, exemplo ou registro de decisão de arquitetura (ADR), ou, para propriedades do formato PDF, pelas cláusulas ISO 32000-2 em citations: no front-matter e na tabela de Conformidade. O comportamento do FPDF é afirmado apenas como “mecanismo independente — espere diferenças documentadas”; esta página não reivindica nenhuma paridade que um artefato do repositório não prove.

afirmação de comportamento do NextPDFEvidência no repositório (caminho)
AddPage mapeia para addPage(?PageSize, Orientation): static.src/Core/Concerns/HasPages.php (addPage()).
SetFont($family, $style, $size) mapeia para setFont(string, string, float): static; estilos ''/'B'/'I'/'BI'/'U'.src/Core/Concerns/HasTypography.php (setFont()).
Cell mapeia para cell($w, $h, $txt, $border, $newLine, $align, $fill): static.src/Core/Concerns/HasTextOutput.php (cell()).
MultiCell mapeia para multiCell($w, $h, $txt, $border, $align): static (quebra baseada em métrica).src/Core/Concerns/HasTextOutput.php (multiCell(), wrapText()).
Write/Text/Ln mapeiam para write()/text()/ln().src/Core/Concerns/HasTextOutput.php (write(), text(), ln()).
SetXY/SetX/SetY/GetX/GetY mapeiam diretamente; SetMargins recebe um VO Margin.src/Core/Concerns/HasPages.php (setXY(), getX(), setMargins()); src/ValueObjects/Margin.php ((top, right, bottom, left)).
Image mapeia para image($file, ?$x, ?$y, ?$w, ?$h): static; rejeita caminhos com scheme/NUL.src/Core/Concerns/HasImages.php (image(), assertImageFilePath()).
Line/Rect/SetLineWidth/SetDrawColor/SetFillColor/SetTextColor mapeiam diretamente.src/Core/Concerns/HasDrawing.php (line(), rect(), setLineWidth()); src/Core/Concerns/HasColors.php (setDrawColor(), setFillColor(), setTextColor()).
A página padrão de createStandalone() é A4 retrato (595.276 × 841.890 pt).src/Core/Document.php (createStandalone()); src/ValueObjects/PageSize.php (A4()).
O destino de saída é o enum OutputDestination (Inline/Download/File/String); Output('S')getPdfData(), Output('F', $p)save($p).src/Contracts/OutputDestination.php; src/Core/Concerns/HasOutput.php (output()).
SetTitle/SetAuthor/… mapeiam para setters de metadados tipados; caem no dicionário de informações / XMP.src/Core/Concerns/HasMetadata.php (setTitle(), setAuthor()); ISO 32000-2 §14 (citations: do front-matter).
As fontes são sempre incorporadas como programas de subset.src/Core/Concerns/HasTypography.php (buildFontData()); ISO 32000-2 §9 (citations: do front-matter).
O conteúdo é emitido em passagem única.docs/architecture/adr/ADR-001-stream-based-rendering-pipeline.md.

Ambos os pacotes permanecem instalados até a transição final, portanto a reversão por local de chamada significa reverter aquele local de chamada para o caminho do FPDF. Após a transição final, a reversão significa restaurar o FPDF e o código anterior a partir do controle de versão. Nenhuma migração de dados está envolvida.

Consulte Desempenho. O modelo de passagem única elimina qualquer custo de buffer retido. O novo custo por documento é a resolução antecipada (eager) de fontes (etapa 3), que pode ser armazenada em cache por meio do diretório de fontes.

  • Transcrever coordenadas em milímetros como pontos sem a conversão * 72 / 25.4.
  • Deixar Output() na ordem ($dest, $name) do FPDF, ou passar um caractere em vez do enum OutputDestination.
  • Transcrever SetMargins($l, $t, $r) direto para Margin (cuja ordem é top, right, bottom, left).
  • Esperar que os arquivos de métrica de AddFont sejam portados; coloque o TTF/OTF no diretório de fontes em vez disso.
  • Recorrer a um equivalente de GetStringWidth; use multiCell() para a quebra.
  • Esperar saída byte/pixel-identical (mecanismos independentes — este guia nunca reivindica um drop-in ou 100% de compatibilidade).