Lewati ke konten

Migrasikan basis kode TCPDF 6.x ke NextPDF

Paket nextpdf/compat-legacy mengekspos nama metode publik, urutan parameter, dan nilai standar TCPDF 6.x di atas mesin inti NextPDF melalui adapter NextPDF\Compat\Tcpdf\TCPDF. Lakukan migrasi dengan urutan ini: pindah ke mesin dengan perubahan sekecil mungkin, buktikan apa yang sudah berfungsi, aktifkan mode ketat untuk menemukan bagian yang belum berfungsi, perbaiki titik panggilan satu per satu, lalu pensiunkan adapter dan gunakan API modern. Adapter membantu proses migrasi; ia bukan tujuan akhir.

Prasyarat, di awal:

  • Inti NextPDF dan nextpdf/compat-legacy telah terpasang.
  • Anda memiliki basis kode TCPDF 6.x yang sudah ada beserta rangkaian ujinya. Rangkaian uji adalah jaring pengaman untuk setiap tahap di bawah ini.

Ini adalah panduan praktis. Untuk perilaku per metode dari satu panggilan TCPDF, baca halaman cakupan metode. Untuk strategi lengkap per file beserta kodenya, baca halaman migrasi hulu. Kedua tautan tersebut ada di bagian Lihat juga.

Pasang adapter berdampingan dengan inti. Jangan menghapus pustaka TCPDF asli terlebih dahulu — mempertahankan keduanya memungkinkan Anda membandingkan keluaran selama migrasi.

Terminal window
composer require nextpdf/compat-legacy

Sebelum Anda mengubah kode apa pun, pastikan dependensi mesin terselesaikan (nextpdf/core ^3.0) dan rangkaian uji masih berjalan.

Adapter adalah lapisan kompatibilitas, bukan fork TCPDF dan bukan tiruan yang identik per byte. Dari sekitar 120 metode publik TCPDF 6.x yang disurvei, sekitar 94 di antaranya dipetakan langsung ke operasi NextPDF\Core\Document dan berperilaku kompatibel untuk parameter yang terdokumentasi. Sebagian kecil yang telah diidentifikasi menerima parameter lawas yang tidak dihormati oleh mesin (diabaikan secara diam-diam), atau tidak menghasilkan keluaran (belum diimplementasikan atau tidak berlaku). Matriks cakupan otoritatif yang telah diverifikasi lewat uji ada di repositori paket pada docs/TCPDF_COVERAGE.md. Bila panduan ini dan matriks tersebut berbeda, matrikslah yang berlaku.

Dua fakta membentuk keseluruhan proses migrasi:

  • Byte keluaran berbeda. Mesin ini adalah implementasi PDF 2.0 yang independen, sehingga byte yang dirender berbeda dari keluaran TCPDF meskipun hasil yang terlihat tampak sama. Uji yang membandingkan byte PDF secara persis perlu dibuat ulang basisnya berdasarkan konten yang dirender atau properti struktural.
  • Mode ketat adalah alat audit Anda. Dengan mode ketat dimatikan (standar), metode yang tidak dapat mereproduksi perilaku TCPDF akan berdegradasi secara diam-diam. Dengan mode ketat diaktifkan, panggilan tersebut melempar TcpdfNotImplementedException, dengan menyebutkan parameter yang diabaikan secara persis beserta petunjuk migrasi. Jalankan mode ketat dalam tahap audit khusus, jangan pernah di produksi.

Adapter juga mengekspos dokumen mesin yang dibungkus melalui getDocument(), yang mengembalikan NextPDF\Core\Document. Gunakan ini sebagai jalan keluar: migrasikan titik panggilan ke API modern satu per satu hingga Anda dapat menghapus adapter.

AspekPermukaan
Konstruksinew NextPDF\Compat\Tcpdf\TCPDF('P', 'mm', 'A4')
Alias global opsionalNextPDF\Compat\Tcpdf\LegacyBootstrap::enableAliases()
Mengaktifkan auditTCPDF::setStrictMode(true)
Pengecualian auditNextPDF\Compat\Tcpdf\Exception\TcpdfNotImplementedException
Jalan keluar ke API modernTCPDF::getDocument(): NextPDF\Core\Document
KeluaranTCPDF::Output(string $name, string $dest)S, F, E, I, D

LegacyBootstrap::enableAliases() bersifat idempoten. Ia mendaftarkan \TCPDF, \TCPDF_STATIC, \TCPDF_FONTS, \TCPDF_COLORS, dan \TCPDF_IMAGES hanya ketika kelas-kelas tersebut belum ada. Halaman cakupan metode dan mulai cepat yang ditautkan di bagian Lihat juga mencakup perilaku per metode secara lengkap serta tujuan keluaran.

Ubah impor, pertahankan panggilan bergaya TCPDF, lalu hasilkan PDF.

quickstart-first.php
<?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') menulis berkas dan mengembalikan string kosong. Tidak seperti TCPDF lawas, Output() milik adapter tidak menggemakan keluaran ke buffer keluaran yang aktif, sehingga Anda dapat memanggilnya dengan aman di dalam pekerja antrean atau penangan HTTP yang mengendalikan responsnya sendiri.

Ketika Anda tidak dapat mengubah titik panggilan yang membuat new \TCPDF(...) di namespace global, aktifkan alias opsional satu kali saat boot.

quickstart-alias.php
<?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');

Jangan aktifkan alias selama pustaka TCPDF asli masih dapat dimuat otomatis. Alias dilewati ketika kelas \TCPDF sudah ada, sehingga Anda mungkin tetap menggunakan TCPDF lawas tanpa menyadarinya. Selama migrasi, utamakan impor per berkas.

Langkah migrasi yang aman adalah menjalankan audit mode ketat. Jalankan jalur produksi yang representatif, atau rangkaian uji, dengan mode ketat diaktifkan, dan kumpulkan setiap TcpdfNotImplementedException. Setiap pengecualian adalah satu butir pekerjaan: ia menyebutkan metodenya, parameter yang diabaikan, dan petunjuknya.

migration-audit.php
<?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");
}

Untuk setiap celah, pilih perbaikan yang benar dengan biaya paling kecil: hapus parameter yang tidak pernah Anda andalkan, atau nyatakan maksudnya melalui API modern via getDocument(). Jalan keluar tersebut menangani apa pun yang tidak dapat dinyatakan oleh permukaan TCPDF.

migration-escape-hatch.php
<?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');

Jalankan mode ketat sebagai tugas integrasi berkelanjutan (CI) khusus, lalu matikan dan deploy jalur kode yang sudah diaudit. Pertahankan tugas CI mode ketat secara berkala untuk menangkap regresi saat Anda melakukan refaktor.

  • MultiCell() mengembalikan 1, Write() mengembalikan 0. Ini adalah nilai pengganti kompatibilitas, bukan nilai yang dihitung. Sesuaikan kode apa pun yang bercabang berdasarkan nilai pengembalian tersebut.
  • Error() melempar pengecualian alih-alih memanggil die(). Adapter memunculkan RuntimeException. Kode yang mengandalkan penghentian proses harus menangkap pengecualian tersebut.
  • Parameter yang diabaikan secara diam-diam. Metode seperti Image(), writeHTML(), SetProtection(), dan Bookmark() menerima parameter lawas yang diabaikan. Gunakan mode ketat untuk menemukannya. Untuk gambar yang dapat diklik, gambar terlebih dahulu lalu tambahkan Document::link() di atas persegi panjang yang sama.
  • Metode yang belum diimplementasikan. setSignature(), addEmptySignatureAppearance(), dan endPage() adalah no-op yang melempar pengecualian dalam mode ketat; Open() adalah no-op aman yang tidak pernah melempar pengecualian. Hapus endPage() dan Open(). Penandatanganan memerlukan edisi NextPDF komersial melalui API tanda tangan modern.
  • Versi PDF bersifat tetap. setPDFVersion() tidak dapat menargetkan versi PDF yang lebih lama; keluaran selalu PDF 2.0. setUserRights() tidak digunakan lagi di PDF 2.0 dan diabaikan dengan sebuah pemberitahuan.
  • Konflik alias. Jika ada apa pun yang masih terselesaikan ke kelas TCPDF asli setelah Anda menghapus tecnickcom/tcpdf, peringatan tentang alias tetap berlaku — impor adapter secara eksplisit di titik panggilan tersebut.

Adapter mendelegasikan ke mesin; biaya pembangunan dokumen berskala mengikuti konten, bukan lapisan adapter. Karena Output() milik adapter tidak menulis ke buffer keluaran, ia aman di dalam pekerja antrean — pindahkan pembuatan bergaya TCPDF yang berat keluar dari thread permintaan dengan cara yang sama seperti Anda memindahkan pembuatan NextPDF apa pun. Membuat ulang basis uji tingkat byte berdasarkan konten yang dirender adalah biaya sekali bayar, dan hal itu memberi Anda uji yang tetap stabil terhadap peningkatan mesin di masa depan.

  • Enkripsi. SetProtection() mengabaikan parameter lawas mode dan pubkeys; mesin menggunakan AES-256 untuk handler standar. Untuk enkripsi berbasis sertifikat, gunakan titik masuk enkripsi kunci publik modern yang diekspos pada adapter, bukan parameter lawas.
  • Penandatanganan dibatasi. Dukungan tanda tangan dasar adalah kemampuan edisi komersial yang dicapai melalui API tanda tangan modern dengan objek nilai sertifikat; setSignature() lawas adalah no-op. Panduan ini tidak membuat klaim apa pun tentang validasi jangka panjang atau profil tanda tangan berstempel waktu untuk edisi mana pun.
  • Gagal secara eksplisit selama audit. Mode ketat membuat parameter yang hilang secara diam-diam menjadi terlihat, sehingga Anda tahu kapan adapter tidak menghormati maksud pemanggil. Perlakukan pengecualian yang terkumpul sebagai daftar pekerjaan migrasi, bukan sebagai perilaku produksi.
  • Jangan pernah menulis blok catch yang kosong. Contoh audit menangkap TcpdfNotImplementedException dan menulis satu baris untuk butir pekerjaan yang sudah ditetapkan.

Postur enkripsi dan tanda tangan lengkap selama migrasi ada di halaman keamanan dan operasi compat-legacy.

Panduan ini tidak membuat klaim standar normatif tersendiri. Adapter menulis keluaran PDF 2.0 (ISO 32000-2) dan tidak dapat menargetkan versi yang lebih lama. Perilaku tersebut dan klausanya dicatat pada halaman cakupan metode hulu, yang juga mencatat prinsip gagal-secara-eksplisit OWASP di balik mode ketat serta kerangka kelengkapan fungsional ISO/IEC 25023 dari audit cakupan. Halaman cookbook ini menyatakan kembali penggunaannya dan menyerahkan kutipan tersebut ke halaman hulu.