Bỏ qua để đến nội dung

Chuyển từ TCPDF 6.x sang NextPDF

Hãy chuyển đổi theo một trình tự rõ ràng. Trước tiên, chuyển sang engine NextPDF với thay đổi nhỏ nhất có thể. Xác minh những phần đã hoạt động. Kiểm tra những phần chưa hoạt động. Sửa từng vị trí gọi. Sau đó gỡ bỏ adapter. Lớp tương thích hỗ trợ các bước từ hai đến bốn; đó không phải là đích đến.

Trang này đưa ra chiến lược chuyển đổi. Để biết hành vi chính xác của từng phương thức riêng lẻ, hãy dùng /integrations/tcpdf-compat/method-coverage/ cùng với bảng đối chiếu chính thức trong 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

Mỗi giai đoạn đều giữ ứng dụng ở trạng thái có thể phát hành. Bạn không cần thực hiện một lần chuyển đổi toàn bộ cùng một lúc.

Cài đặt nextpdf/compat-legacy (xem /integrations/tcpdf-compat/install/). Chưa gỡ bỏ tecnickcom/tcpdf vội; giữ cả hai để bạn có thể so sánh kết quả.

Hãy chọn cách để các vị trí gọi cũ phân giải lớp:

  • Khuyến nghị: đổi use/require trong từng tệp thành use NextPDF\Compat\Tcpdf\TCPDF;. Cách này rõ ràng và dễ tìm kiếm.
  • Khi chưa thể chạm vào các vị trí gọi: hãy bật các alias toàn cục tùy chọn một lần khi khởi động bằng LegacyBootstrap::enableAliases() (xem /integrations/tcpdf-compat/boot-and-discovery/). Cách này phân giải \TCPDF và bốn lớp trợ giúp sang adapter.

Trên thực tế, hai chiến lược này loại trừ lẫn nhau. Nếu thư viện TCPDF thực sự vẫn có thể tự nạp và bạn bật các alias toàn cục, thì alias sẽ bị bỏ qua khi lớp \TCPDF đã tồn tại. Khi đó bạn có thể tiếp tục dùng TCPDF cũ mà không nhận ra. Trong Giai đoạn 1, hãy ưu tiên nhập theo từng tệp để bạn biết chính xác mỗi vị trí gọi dùng lớp nào. Xem /integrations/tcpdf-compat/troubleshooting/.

Giai đoạn 2 — Chạy bộ kiểm thử hiện có mà không thay đổi gì

Phần tiêu đề “Giai đoạn 2 — Chạy bộ kiểm thử hiện có mà không thay đổi gì”

Hãy chạy toàn bộ bộ kiểm thử trên adapter mà không thay đổi gì khác. Phần lớn các phương thức được ủy quyền (94 trong số khoảng 120 phương thức được khảo sát) hoạt động tương thích. Hãy dự kiến hai nhóm lỗi có thể đoán trước:

  1. Các phép kiểm tra ở mức byte. Các kiểm thử so sánh chính xác từng byte Portable Document Format (PDF) sẽ thất bại vì engine là một bản triển khai độc lập. Đây là điều dự kiến, không phải lỗi. Hãy hoãn các kiểm thử này đến Giai đoạn 4.
  2. Các nhánh dựa trên giá trị trả về. Một vài phương thức trả về giá trị thay thế nhằm tương thích thay vì giá trị đã tính toán. Đáng chú ý nhất, MultiCell() trả về 1, và Write() trả về 0. Đoạn mã phân nhánh dựa trên các giá trị trả về đó cần được điều chỉnh.

Hãy lập danh mục mọi lỗi. Hãy phân loại từng lỗi là byte-baseline, return-value, hoặc khoảng chênh hành vi thực sự.

Giai đoạn 3 — Kiểm tra ở chế độ strict

Phần tiêu đề “Giai đoạn 3 — Kiểm tra ở chế độ strict”

Giai đoạn này giúp quá trình chuyển đổi an toàn hơn. Hãy chạy bộ kiểm thử, hoặc một luồng production tiêu biểu, khi đã bật chế độ strict:

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");
}

Hãy xem mỗi TcpdfNotImplementedException là một hạng mục công việc. Thông báo cho biết phương thức, danh sách chính xác các tham số bị bỏ qua, và một gợi ý chuyển đổi. Tập hợp các phương thức ném ngoại lệ được liệt kê và kiểm tra trong tests/Unit/Compat/Tcpdf/TcpdfStrictModeTest.php. Lý do của từng trường hợp nằm trong docs/TCPDF_COVERAGE.md.

Hãy chạy chế độ strict như một công việc tích hợp liên tục (CI) chuyên dụng, không phải trong production. Mục đích là phát hiện các khoảng chênh, chứ không phải khiến production ném ngoại lệ.

Với mỗi khoảng chênh, hãy chọn cách sửa đúng và ít tốn kém nhất:

Dạng khoảng chênhCách sửa
Tham số bị bỏ qua không quan trọng (e.g. một $align của TCPDF mà bạn chưa từng dựa vào)Bỏ tham số đó. Lệnh gọi sẽ trở nên tương thích (không phải byte-identical).
Tham số bị bỏ qua có quan trọng (e.g. một liên kết Image() có thể nhấp được)Hãy diễn đạt lại bằng API hiện đại. Vẽ hình ảnh, rồi thêm Document::link() lên trên hình chữ nhật.
Phương thức chưa được triển khai (setSignature(), endPage())endPage() / Open(): xóa lệnh gọi. Ký: xem /integrations/tcpdf-compat/security-and-operations/; tính năng này yêu cầu phiên bản thương mại.
Phương thức không áp dụng được (setPDFVersion(), setUserRights())Xóa lệnh gọi. Kết quả đầu ra luôn là PDF 2.0; user-rights đã ngừng dùng trong PDF 2.0.
Nhánh dựa trên giá trị trả vềTự tính giá trị, hoặc chuyển logic đó sang API hiện đại.

Hãy dùng lối thoát khi bề mặt TCPDF không thể diễn đạt điều bạn cần:

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');

Thiết lập lại baseline cho các kiểm thử ở mức byte

Phần tiêu đề “Thiết lập lại baseline cho các kiểm thử ở mức byte”

Hãy thay các phép kiểm tra chính xác từng byte bằng những phép kiểm tra nhắm vào điều thực sự quan trọng:

  • Kết quả đầu ra bắt đầu bằng %PDF và phân tích được (mức smoke).
  • Nội dung văn bản đã kết xuất có mặt (trích xuất văn bản rồi kiểm tra trên đó).
  • Các thuộc tính cấu trúc (số trang, kích thước trang, và sự hiện diện của outline) khớp nhau.

Chi phí một lần này mang lại cho bạn những kiểm thử có thể tồn tại qua các lần nâng cấp engine trong tương lai.

Sau khi việc kiểm tra ở chế độ strict thành công, chế độ strict đã tắt trong production, và bộ kiểm thử xanh với các phép kiểm tra đã thiết lập lại baseline, hãy gỡ bỏ tecnickcom/tcpdf:

Terminal window
composer remove tecnickcom/tcpdf

Hãy chạy lại bộ kiểm thử. Nếu vẫn còn thứ gì phân giải tới lớp TCPDF thực sự, thì cảnh báo về alias ở Giai đoạn 1 vẫn áp dụng; hãy sửa các vị trí gọi còn lại để nhập adapter một cách tường minh.

Adapter là công cụ hỗ trợ chuyển đổi, không phải lớp dùng lâu dài. Sau khi TCPDF đã được loại bỏ và engine đã được kiểm chứng, hãy loại bỏ adapter dần dần:

  1. Trong từng module, hãy thay new TCPDF(...) bằng cách khởi tạo NextPDF\Core\Document hiện đại.
  2. Hãy thay các lệnh gọi phương thức TCPDF bằng phương thức hiện đại tương đương (các lệnh gọi getDocument() mà bạn đã thêm ở Giai đoạn 4 là mẫu để làm theo).
  3. Khi một module không còn tham chiếu đến adapter, hãy xóa các lệnh nhập tương thích của nó.
  4. Khi không còn module nào tham chiếu đến adapter, hãy gỡ bỏ nextpdf/compat-legacy khỏi composer.json.

Tại thời điểm đó, bạn đang dùng API PDF 2.0 hiện đại mà không còn lớp tương thích.

  • Đã cài đặt nextpdf/compat-legacy; đã xác minh liên kết engine.
  • Các vị trí gọi nhập adapter một cách tường minh (hoặc đã bật các alias khi TCPDF thực sự đã được gỡ khỏi đường dẫn tự nạp).
  • Đã chạy toàn bộ bộ kiểm thử trên adapter; đã phân loại các lỗi.
  • Đã thêm công việc CI chế độ strict; đã lập danh mục mọi khoảng chênh.
  • Đã sửa từng khoảng chênh (bỏ tham số / API hiện đại / xóa lệnh gọi).
  • Đã thiết lập lại baseline cho các phép kiểm tra ở mức byte theo nội dung và cấu trúc.
  • Đã gỡ bỏ tecnickcom/tcpdf; bộ kiểm thử xanh.
  • Đã loại bỏ adapter theo từng module; đã gỡ bỏ dependency.
  • /integrations/tcpdf-compat/method-coverage/ — hành vi của từng phương thức và hướng dẫn thay thế
  • docs/TCPDF_COVERAGE.md — bảng đối chiếu chính thức, đã được kiểm thử xác minh
  • /integrations/tcpdf-compat/configuration/ — chuyển cấu hình khỏi các hằng số toàn cục
  • /integrations/tcpdf-compat/security-and-operations/ — mã hóa và ký trong quá trình chuyển đổi
  • /integrations/tcpdf-compat/troubleshooting/ — xung đột alias/real-TCPDF và các bẫy khác