Lewati ke konten

Migrasi dari TCPDF 6.x ke NextPDF

Jalankan migrasi dalam urutan yang jelas. Beralihlah ke mesin NextPDF terlebih dahulu dengan perubahan sekecil mungkin. Verifikasi bagian yang sudah berfungsi. Audit bagian yang belum. Perbaiki setiap lokasi pemanggilan, lalu hapus adaptornya. Lapisan kompatibilitas mendukung langkah dua hingga empat; lapisan ini bukan tujuan akhir.

Halaman ini menjelaskan strateginya. Untuk perilaku tepat setiap metode individual, gunakan /integrations/tcpdf-compat/method-coverage/ bersama matriks otoritatif di repo docs/TCPDF_COVERAGE.md.

TCPDF 6.x codebase

Swap dependency: install compat-legacy

Run existing suite unchanged

Strict-mode audit: enumerate behavioral gaps

Fix call sites: drop ignored params or move to modern API

Re-baseline byte-level test assertions

Remove the TCPDF dependency

Incrementally retire the adapter onto Document

Diagram

Setiap tahap menjaga aplikasi tetap siap rilis. Anda tidak pernah perlu melakukan peralihan sekaligus dalam satu langkah.

Pasang nextpdf/compat-legacy (lihat /integrations/tcpdf-compat/install/). Jangan hapus tecnickcom/tcpdf dulu; mempertahankan keduanya memungkinkan Anda membandingkan hasil.

Pilih cara lokasi pemanggilan lama menyelesaikan kelas tersebut:

  • Disarankan: ubah use/require pada setiap berkas menjadi use NextPDF\Compat\Tcpdf\TCPDF;. Cara ini eksplisit dan mudah ditelusuri.
  • Jika Anda belum dapat mengubah lokasi pemanggilan: aktifkan alias global opsional satu kali saat boot dengan LegacyBootstrap::enableAliases() (lihat /integrations/tcpdf-compat/boot-and-discovery/). Ini menyelesaikan \TCPDF dan empat kelas pembantu ke adaptor.

Kedua strategi tersebut saling eksklusif dalam praktiknya. Jika pustaka TCPDF asli tetap dapat dimuat otomatis dan Anda mengaktifkan alias global, alias akan dilewati ketika kelas \TCPDF sudah ada. Akibatnya, Anda bisa terus menggunakan TCPDF lama tanpa menyadarinya. Selama Tahap 1, lebih baik gunakan impor per berkas agar Anda tahu persis kelas mana yang digunakan oleh setiap lokasi pemanggilan. Lihat /integrations/tcpdf-compat/troubleshooting/.

Tahap 2 — Jalankan rangkaian pengujian yang ada tanpa perubahan

Bagian berjudul “Tahap 2 — Jalankan rangkaian pengujian yang ada tanpa perubahan”

Jalankan seluruh rangkaian pengujian Anda terhadap adaptor tanpa mengubah hal lain. Sebagian besar metode yang didelegasikan (94 dari ~120 yang disurvei) berperilaku kompatibel. Antisipasi dua kelas kegagalan yang dapat diprediksi:

  1. Asersi tingkat bita. Pengujian yang membandingkan bita Portable Document Format (PDF) secara persis akan gagal karena mesin ini merupakan implementasi independen. Ini sudah diperkirakan, bukan cacat. Tunda ini hingga Tahap 4.
  2. Percabangan nilai balik. Beberapa metode mengembalikan nilai placeholder untuk kompatibilitas, bukan nilai hasil perhitungan. Yang paling menonjol, MultiCell() mengembalikan 1, dan Write() mengembalikan 0. Kode yang membuat percabangan berdasarkan nilai balik tersebut perlu disesuaikan.

Catat setiap kegagalan. Klasifikasikan masing-masing sebagai byte-baseline, return-value, atau kesenjangan perilaku sejati.

Tahap ini membuat migrasi aman. Jalankan rangkaian pengujian, atau jalur produksi yang representatif, dengan mode ketat diaktifkan:

examples/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 $e) {
// Each message names the method, the ignored parameters, and a hint.
fwrite(STDERR, 'MIGRATION GAP: ' . $e->getMessage() . "\n");
}

Perlakukan setiap TcpdfNotImplementedException sebagai satu item pekerjaan. Pesan tersebut mencantumkan metode, daftar parameter yang diabaikan secara persis, dan petunjuk migrasi. Kumpulan metode yang melemparkan eksepsi sudah dienumerasi dan diuji dengan asersi di tests/Unit/Compat/Tcpdf/TcpdfStrictModeTest.php. Alasan untuk masing-masing ada di docs/TCPDF_COVERAGE.md.

Jalankan mode ketat sebagai pekerjaan integrasi berkelanjutan (CI) khusus, bukan di produksi. Tujuannya adalah mengungkap kesenjangan, bukan membuat produksi melemparkan eksepsi.

Untuk setiap kesenjangan, pilih perbaikan yang benar dengan biaya paling rendah:

Pola kesenjanganPerbaikan
Parameter yang diabaikan tidak penting (e.g. $align TCPDF yang tidak pernah Anda andalkan)Hapus parameternya. Pemanggilan menjadi persis kompatibel.
Parameter yang diabaikan ternyata penting (e.g. tautan Image() yang dapat diklik)Nyatakan ulang dengan API modern. Render citra, lalu tambahkan Document::link() di atas persegi panjang tersebut.
Metode yang belum diimplementasikan (setSignature(), endPage())endPage() / Open(): hapus pemanggilannya. Penandatanganan: lihat /integrations/tcpdf-compat/security-and-operations/; ini membutuhkan edisi komersial.
Metode yang tidak lagi berlaku (setPDFVersion(), setUserRights())Hapus pemanggilannya. Keluaran selalu PDF 2.0; user-rights tidak digunakan lagi di PDF 2.0.
Percabangan nilai balikHitung sendiri nilainya, atau pindahkan logika tersebut ke API modern.

Gunakan escape hatch saat permukaan API TCPDF tidak dapat menyatakan kebutuhan Anda:

examples/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 as-is for the parts that work:
$pdf->SetFont('helvetica', '', 12);
$pdf->Cell(0, 10, 'Header line', 0, 1);
// Modern path for what the TCPDF surface cannot express here:
$document = $pdf->getDocument();
$document->image('logo.png', 10, 30, 40, 0);
$document->link(10, 30, 40, 20, 'https://example.com');

Tetapkan ulang baseline pengujian tingkat bita

Bagian berjudul “Tetapkan ulang baseline pengujian tingkat bita”

Ganti asersi bita-persis dengan asersi terhadap hal yang penting:

  • Keluaran diawali dengan %PDF dan dapat diurai (tingkat smoke).
  • Konten teks yang dirender hadir (ekstrak teks dan lakukan asersi terhadapnya).
  • Properti struktural (jumlah halaman, ukuran halaman, dan keberadaan outline) cocok.

Biaya satu kali ini menghasilkan pengujian yang bertahan terhadap pemutakhiran mesin di masa mendatang.

Setelah audit mode ketat lolos, mode ketat nonaktif di produksi, dan rangkaian pengujian hijau pada asersi yang baseline-nya sudah ditetapkan ulang, hapus tecnickcom/tcpdf:

Terminal window
composer remove tecnickcom/tcpdf

Jalankan rangkaian pengujian lagi. Jika masih ada lokasi yang diselesaikan ke kelas TCPDF asli, peringatan alias di Tahap 1 berlaku; perbaiki lokasi pemanggilan yang tersisa untuk mengimpor adaptor secara eksplisit.

Adaptor adalah alat bantu migrasi, bukan lapisan permanen. Setelah TCPDF sudah tidak ada dan mesin terbukti berjalan, pensiunkan adaptor secara bertahap:

  1. Pada setiap modul, ganti new TCPDF(...) dengan konstruksi modern NextPDF\Core\Document.
  2. Ganti pemanggilan metode TCPDF dengan padanan modernnya (pemanggilan getDocument() yang sudah Anda tambahkan di Tahap 4 menjadi templatnya).
  3. Ketika sebuah modul tidak lagi merujuk ke adaptor, hapus impor kompatibilitasnya.
  4. Ketika tidak ada modul yang merujuk ke adaptor, hapus nextpdf/compat-legacy dari composer.json.

Pada titik tersebut, Anda sudah berada di API PDF 2.0 modern tanpa lapisan kompatibilitas.

  • nextpdf/compat-legacy terpasang; koneksi mesin terverifikasi.
  • Lokasi pemanggilan mengimpor adaptor secara eksplisit (atau alias diaktifkan dengan TCPDF asli dihapus dari jalur muat-otomatis).
  • Seluruh rangkaian pengujian dijalankan terhadap adaptor; kegagalan diklasifikasikan.
  • Pekerjaan CI mode ketat ditambahkan; setiap kesenjangan dicatat.
  • Setiap kesenjangan diperbaiki (hapus parameter / API modern / hapus pemanggilan).
  • Asersi tingkat bita ditetapkan ulang baseline-nya ke konten dan struktur.
  • tecnickcom/tcpdf dihapus; rangkaian pengujian hijau.
  • Adaptor dipensiunkan modul demi modul; dependensi dihapus.
  • /integrations/tcpdf-compat/method-coverage/ — perilaku per metode dan panduan penggantian
  • docs/TCPDF_COVERAGE.md — matriks otoritatif yang diverifikasi pengujian
  • /integrations/tcpdf-compat/configuration/ — memindahkan konfigurasi dari konstanta global
  • /integrations/tcpdf-compat/security-and-operations/ — enkripsi dan penandatanganan selama migrasi
  • /integrations/tcpdf-compat/troubleshooting/ — konflik alias/real-TCPDF dan jebakan lainnya