Migre uma base de código TCPDF 6.x para o NextPDF
Visão geral
Seção intitulada “Visão geral”O pacote nextpdf/compat-legacy expõe os nomes de métodos públicos, a ordem dos parâmetros e os valores padrão do TCPDF 6.x sobre o motor do core do NextPDF por meio do adaptador NextPDF\Compat\Tcpdf\TCPDF. Siga esta ordem de migração: troque para o motor com a menor alteração possível, comprove o que já funciona, ative o modo estrito para encontrar o que ainda não funciona, corrija os pontos de chamada um de cada vez e, depois, aposente o adaptador e use a API moderna. O adaptador apoia a migração; ele não é o destino.
Pré-requisitos antes de começar:
- O core do NextPDF e o
nextpdf/compat-legacyestão instalados. - Você tem uma base de código TCPDF 6.x existente com uma suíte de testes. A suíte é a rede de segurança para cada etapa abaixo.
Este é um guia prático. Para entender o comportamento de cada método em uma chamada TCPDF, leia a página de cobertura de métodos. Para a estratégia completa arquivo por arquivo, com código, leia a página de migração upstream. Os dois links estão na seção Veja também.
Instalação
Seção intitulada “Instalação”Instale o adaptador junto com o core. Não remova ainda a biblioteca TCPDF real — manter as duas permite comparar a saída durante a migração.
composer require nextpdf/compat-legacyAntes de alterar qualquer código, confirme que o vínculo com o motor é resolvido (nextpdf/core ^3.0) e que a suíte ainda executa.
Visão conceitual
Seção intitulada “Visão conceitual”O adaptador é uma camada de compatibilidade, não um fork do TCPDF nem um clone byte-idêntico. Dos cerca de 120 métodos públicos do TCPDF 6.x analisados, aproximadamente 94 mapeiam diretamente para uma operação de NextPDF\Core\Document e se comportam de forma compatível para os parâmetros documentados. Uma minoria define ou aceita parâmetros legados que o motor não respeita (ignorados silenciosamente), ou não produz saída alguma (não implementados ou não aplicáveis). A matriz de cobertura oficial, verificada por testes, está no repositório do pacote em docs/TCPDF_COVERAGE.md. Se este guia e essa matriz divergirem, a matriz prevalece.
Dois fatos moldam toda a migração:
- Os bytes de saída diferem. O motor é uma implementação independente de PDF 2.0, portanto os bytes renderizados diferem da saída do TCPDF mesmo quando o resultado visível parece igual. Testes que verificam os bytes exatos do PDF precisam ter sua linha de base refeita com base no conteúdo renderizado ou em propriedades estruturais.
- O modo estrito é a sua ferramenta de auditoria. Com o modo estrito desativado (o padrão), os métodos que não conseguem reproduzir o comportamento do TCPDF degradam silenciosamente. Com o modo estrito ativado, essas chamadas lançam
TcpdfNotImplementedException, informando exatamente os parâmetros ignorados e uma dica de migração. Execute o modo estrito em uma passagem de auditoria dedicada, nunca em produção.
O adaptador também expõe o documento do motor que ele encapsula por meio de getDocument(), que retorna o NextPDF\Core\Document. Use isso como o caminho de saída: migre os pontos de chamada para a API moderna um de cada vez até poder remover o adaptador.
Superfície da API
Seção intitulada “Superfície da API”| Tópico | Superfície |
|---|---|
| Construir | new NextPDF\Compat\Tcpdf\TCPDF('P', 'mm', 'A4') |
| Aliases globais opcionais | NextPDF\Compat\Tcpdf\LegacyBootstrap::enableAliases() |
| Ativar a auditoria | TCPDF::setStrictMode(true) |
| Exceção de auditoria | NextPDF\Compat\Tcpdf\Exception\TcpdfNotImplementedException |
| Saída de emergência para a API moderna | TCPDF::getDocument(): NextPDF\Core\Document |
| Saída | TCPDF::Output(string $name, string $dest) — S, F, E, I, D |
LegacyBootstrap::enableAliases() é idempotente. Ela registra \TCPDF, \TCPDF_STATIC, \TCPDF_FONTS, \TCPDF_COLORS e \TCPDF_IMAGES apenas quando essas classes ainda não existem. As páginas de cobertura de métodos e de início rápido vinculadas em Veja também cobrem o comportamento completo de cada método e os destinos de saída.
Exemplo de código — Início rápido
Seção intitulada “Exemplo de código — Início rápido”Altere o import, mantenha as chamadas no estilo TCPDF e gere um PDF.
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\TCPDF;
$pdf = new TCPDF('P', 'mm', 'A4');$pdf->SetCreator('Quickstart');$pdf->SetTitle('First Document');$pdf->SetFont('helvetica', '', 12);$pdf->AddPage();$pdf->Cell(0, 10, 'Hello from the NextPDF engine', 1, 1, 'C');
$pdf->Output(__DIR__ . '/quickstart.pdf', 'F');Output($name, 'F') grava o arquivo e retorna uma string vazia. Diferentemente do TCPDF legado, o Output() do adaptador não escreve no buffer de saída ativo, então você pode chamá-lo com segurança dentro de um worker de fila ou de um handler HTTP que controla a própria resposta.
Quando você não pode alterar pontos de chamada que instanciam new \TCPDF(...) no namespace global, ative os aliases opcionais uma vez na inicialização.
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\LegacyBootstrap;
LegacyBootstrap::enableAliases();
// Legacy code now resolves \TCPDF to the adapter:$pdf = new \TCPDF('P', 'mm', 'A4');$pdf->AddPage();$pdf->SetFont('helvetica', '', 12);$pdf->Cell(0, 10, 'Legacy call site, modern engine');$pdf->Output(__DIR__ . '/aliased.pdf', 'F');Não ative aliases enquanto a biblioteca TCPDF real ainda puder ser carregada por autoload. O alias é ignorado quando uma classe \TCPDF já existe, então você pode continuar usando o TCPDF legado sem perceber. Durante a migração, prefira imports por arquivo.
Exemplo de código — Produção
Seção intitulada “Exemplo de código — Produção”A etapa segura da migração é a auditoria em modo estrito. Execute um fluxo de produção representativo, ou a suíte, com o modo estrito ativado, e colete cada TcpdfNotImplementedException. Cada exceção é um item de trabalho: ela informa o método, os parâmetros ignorados e uma dica.
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\Exception\TcpdfNotImplementedException;use NextPDF\Compat\Tcpdf\TCPDF;
function renderInvoice(TCPDF $pdf): void{ // ... your existing rendering code, unchanged ...}
$pdf = new TCPDF('P', 'mm', 'A4');$pdf->setStrictMode(true);
try { renderInvoice($pdf); $pdf->Output(__DIR__ . '/audit.pdf', 'F');} catch (TcpdfNotImplementedException $exception) { // Each message names the method, the ignored parameters, and a hint. fwrite(STDERR, 'MIGRATION GAP: ' . $exception->getMessage() . "\n");}Para cada lacuna, escolha a correção correta de menor custo: descarte um parâmetro do qual você nunca dependeu, ou expresse a intenção por meio da API moderna via getDocument(). A saída de emergência lida com tudo o que a superfície do TCPDF não consegue expressar.
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\TCPDF;
$pdf = new TCPDF();$pdf->AddPage();
// Legacy path stays for the parts that already work:$pdf->SetFont('helvetica', '', 12);$pdf->Cell(0, 10, 'Header line', 0, 1);
// Modern path for what the TCPDF surface cannot express here —// for example a clickable image (the legacy Image() link parameter// is one of the silently ignored parameters):$document = $pdf->getDocument();$document->image('logo.png', 10, 30, 40, 0);$document->link(10, 30, 40, 20, 'https://example.com');Execute o modo estrito como um job dedicado de integração contínua (CI) e, em seguida, desative-o e implante o caminho de código auditado. Mantenha um job de CI periódico em modo estrito para capturar regressões à medida que você refatora.
Casos extremos e pegadinhas
Seção intitulada “Casos extremos e pegadinhas”MultiCell()retorna1,Write()retorna0. Esses são marcadores de compatibilidade, não valores calculados. Ajuste qualquer código que desvie o fluxo com base nesses valores de retorno.Error()lança uma exceção em vez de chamardie(). O adaptador lançaRuntimeException. Código que depende do encerramento do processo deve capturar a exceção.- Parâmetros ignorados silenciosamente. Métodos como
Image(),writeHTML(),SetProtection()eBookmark()aceitam parâmetros legados que são ignorados. Use o modo estrito para encontrá-los. Para uma imagem clicável, desenhe a imagem e, em seguida, adicioneDocument::link()sobre o mesmo retângulo. - Métodos não implementados.
setSignature(),addEmptySignatureAppearance()eendPage()são no-ops que lançam exceção no modo estrito;Open()é um no-op seguro que nunca lança exceção. RemovaendPage()eOpen(). A assinatura requer uma edição comercial do NextPDF por meio da API de assinatura moderna. - A versão do PDF é fixa.
setPDFVersion()não pode mirar uma versão mais antiga do PDF; a saída é sempre PDF 2.0.setUserRights()está obsoleto no PDF 2.0 e é ignorado com um aviso. - Conflito de alias. Se algo ainda for resolvido para a classe TCPDF real depois de você remover
tecnickcom/tcpdf, a ressalva do alias se aplica — importe o adaptador explicitamente nesses pontos de chamada.
Desempenho
Seção intitulada “Desempenho”O adaptador delega ao motor; o custo de construção do documento escala com o conteúdo, não com a camada do adaptador. Como o Output() do adaptador não escreve no buffer de saída, ele é seguro dentro de um worker de fila — mova a geração pesada no estilo TCPDF para fora da thread da requisição da mesma forma que você moveria qualquer geração do NextPDF. Refazer a linha de base de testes em nível de bytes com base no conteúdo renderizado é um custo único, e oferece a você testes que sobrevivem a futuras atualizações do motor.
Notas de segurança
Seção intitulada “Notas de segurança”- Criptografia.
SetProtection()ignora os parâmetros legadosmodeepubkeys; o motor usa AES-256 para o handler padrão. Para criptografia baseada em certificado, use o ponto de entrada moderno de criptografia de chave pública exposto no adaptador, não os parâmetros legados. - A assinatura é restrita. O suporte a assinatura baseline é uma capacidade da edição comercial alcançada por meio da API de assinatura moderna com um objeto de valor de certificado; o
setSignature()legado é um no-op. Este guia não faz afirmações sobre perfis de assinatura com validação de longo prazo ou com carimbo de tempo para nenhuma edição. - Falhe explicitamente durante a auditoria. O modo estrito torna visível a perda silenciosa de parâmetros, de modo que você saiba quando o adaptador não respeitou a intenção de quem chamou. Trate as exceções coletadas como a lista de trabalho da migração, não como comportamento de produção.
- Nunca escreva um bloco
catchvazio. O exemplo de auditoria capturaTcpdfNotImplementedExceptione escreve uma linha bem definida para o item de trabalho.
A postura completa de criptografia e assinatura durante a migração está na página de segurança e operações do compat-legacy.
Conformidade
Seção intitulada “Conformidade”Este guia não faz nenhuma afirmação normativa de padrões por conta própria. O adaptador gera saída em PDF 2.0 (ISO 32000-2) e não pode mirar uma versão mais antiga. Esse comportamento e sua cláusula estão fixados na página de cobertura de métodos upstream, que também registra o princípio OWASP de falhar explicitamente por trás do modo estrito e o enquadramento de completude funcional da ISO/IEC 25023 da auditoria de cobertura. Esta página do cookbook reafirma o uso e remete essas citações à página upstream.
Veja também
Seção intitulada “Veja também”- Retornar um PDF gerado a partir de um controller — retorne a saída do adaptador como uma resposta HTTP.
- Início rápido do compat-legacy — primeiro documento, destinos de saída e a saída de emergência.
- Cobertura de métodos do TCPDF — a auditoria método a método e a matriz oficial.
- Migrar do TCPDF 6.x para o NextPDF — a estratégia completa de seis estágios com código.