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

Di chuyển mã nguồn TCPDF 6.x sang NextPDF

Gói nextpdf/compat-legacy cung cấp các tên phương thức công khai, thứ tự tham số và giá trị mặc định của TCPDF 6.x trên nền công cụ NextPDF core thông qua bộ chuyển đổi NextPDF\Compat\Tcpdf\TCPDF. Hãy di chuyển theo trình tự này: chuyển sang công cụ với thay đổi nhỏ nhất, xác nhận những phần đang chạy đúng, bật chế độ nghiêm ngặt để tìm những phần chưa đúng, sửa lần lượt từng nơi gọi, rồi gỡ bỏ bộ chuyển đổi và dùng API hiện đại. Bộ chuyển đổi hỗ trợ quá trình di chuyển; nó không phải là đích đến.

Các điều kiện cần có:

  • NextPDF core và nextpdf/compat-legacy đã được cài.
  • Bạn có một mã nguồn TCPDF 6.x hiện có kèm bộ kiểm thử. Bộ kiểm thử là lưới an toàn cho từng giai đoạn bên dưới.

Đây là hướng dẫn thao tác. Để biết hành vi theo từng phương thức của một lời gọi TCPDF, hãy đọc trang phạm vi phương thức. Để biết chiến lược đầy đủ theo từng tệp kèm mã, hãy đọc trang di chuyển ở thượng nguồn. Cả hai liên kết đều nằm trong mục Xem thêm.

Cài bộ chuyển đổi cùng với core. Đừng vội gỡ thư viện TCPDF thật — giữ cả hai để bạn có thể so sánh kết quả trong khi di chuyển.

Terminal window
composer require nextpdf/compat-legacy

Trước khi đổi bất kỳ mã nào, hãy xác nhận rằng phần phụ thuộc tới công cụ được phân giải (nextpdf/core ^3.0) và bộ kiểm thử vẫn chạy được.

Bộ chuyển đổi là một lớp tương thích, không phải bản tách nhánh của TCPDF và cũng không phải bản sao giống hệt theo byte. Trong khoảng 120 phương thức công khai TCPDF 6.x được khảo sát, khoảng 94 phương thức ánh xạ trực tiếp tới một thao tác NextPDF\Core\Document và hoạt động tương thích với các tham số đã được ghi tài liệu. Một số ít phương thức được định nghĩa hoặc vẫn nhận các tham số cũ mà công cụ không tôn trọng (bỏ qua âm thầm), hoặc không tạo ra kết quả nào (chưa hiện thực hoặc không áp dụng). Ma trận phạm vi có thẩm quyền, đã được kiểm thử xác minh, nằm trong kho gói tại docs/TCPDF_COVERAGE.md. Khi hướng dẫn này và ma trận đó mâu thuẫn, ma trận thắng.

Hai sự thật định hình toàn bộ quá trình di chuyển:

  • Byte kết quả khác nhau. Công cụ là một bản hiện thực PDF 2.0 độc lập, nên các byte được kết xuất khác với kết quả của TCPDF ngay cả khi kết quả hiển thị trông giống nhau. Các bài kiểm thử khẳng định trên byte PDF chính xác cần được tạo lại chuẩn so sánh dựa trên nội dung được kết xuất hoặc các thuộc tính cấu trúc.
  • Chế độ nghiêm ngặt là công cụ kiểm toán của bạn. Khi chế độ nghiêm ngặt tắt (mặc định), những phương thức không thể tái hiện hành vi TCPDF sẽ suy giảm âm thầm. Khi chế độ nghiêm ngặt bật, các lời gọi đó ném TcpdfNotImplementedException, nêu rõ chính xác các tham số bị bỏ qua và một gợi ý di chuyển. Hãy chạy chế độ nghiêm ngặt trong một lượt kiểm toán riêng, không bao giờ chạy trong môi trường sản xuất.

Bộ chuyển đổi cũng phơi bày đối tượng tài liệu của công cụ bên trong thông qua getDocument(), hàm này trả về NextPDF\Core\Document. Hãy dùng nó làm lối ra: di chuyển lần lượt từng nơi gọi sang API hiện đại cho đến khi bạn có thể gỡ bỏ bộ chuyển đổi.

Mối quan tâmBề mặt
Khởi tạonew NextPDF\Compat\Tcpdf\TCPDF('P', 'mm', 'A4')
Bật bí danh toàn cục tùy chọnNextPDF\Compat\Tcpdf\LegacyBootstrap::enableAliases()
Bật kiểm toánTCPDF::setStrictMode(true)
Ngoại lệ kiểm toánNextPDF\Compat\Tcpdf\Exception\TcpdfNotImplementedException
Lối thoát sang API hiện đạiTCPDF::getDocument(): NextPDF\Core\Document
XuấtTCPDF::Output(string $name, string $dest)S, F, E, I, D

LegacyBootstrap::enableAliases() có tính idempotent. Nó đăng ký \TCPDF, \TCPDF_STATIC, \TCPDF_FONTS, \TCPDF_COLORS, và \TCPDF_IMAGES chỉ khi các lớp đó chưa tồn tại. Các trang phạm vi phương thức và bắt đầu nhanh được liên kết trong mục Xem thêm bao quát đầy đủ hành vi theo từng phương thức và các đích xuất.

Đổi câu lệnh import, giữ nguyên các lời gọi kiểu TCPDF, rồi tạo một 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') ghi tệp và trả về một chuỗi rỗng. Khác với TCPDF cũ, Output() của bộ chuyển đổi không ghi vào bộ đệm xuất đang hoạt động, nên bạn có thể yên tâm gọi nó bên trong một queue worker hoặc một trình xử lý HTTP tự kiểm soát phản hồi của riêng nó.

Khi bạn chưa thể đổi các nơi gọi khởi tạo new \TCPDF(...) trên không gian tên toàn cục, hãy bật các bí danh tùy chọn một lần lúc khởi động.

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

Đừng bật các bí danh khi thư viện TCPDF thật vẫn còn có thể được nạp tự động. Bí danh sẽ bị bỏ qua khi một lớp \TCPDF đã tồn tại, nên bạn có thể vẫn đang dùng TCPDF cũ mà không nhận ra. Trong quá trình di chuyển, hãy ưu tiên import theo từng tệp.

Bước di chuyển an toàn là một lượt kiểm toán ở chế độ nghiêm ngặt. Hãy chạy một đường đi sản xuất tiêu biểu, hoặc bộ kiểm thử, với chế độ nghiêm ngặt bật, và thu thập mọi TcpdfNotImplementedException. Mỗi ngoại lệ là một hạng mục công việc: nó nêu tên phương thức, các tham số bị bỏ qua, và một gợi ý.

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

Với mỗi khác biệt, hãy chọn cách sửa đúng và ít tốn kém nhất: bỏ một tham số mà bạn chưa từng dựa vào, hoặc diễn đạt ý định qua API hiện đại bằng getDocument(). Lối thoát này xử lý mọi thứ mà bề mặt TCPDF không thể diễn đạt.

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

Hãy chạy chế độ nghiêm ngặt như một tác vụ tích hợp liên tục (CI) riêng, rồi tắt chế độ đó và triển khai đường đi mã đã được kiểm toán. Giữ một tác vụ CI chế độ nghiêm ngặt định kỳ để bắt các hồi quy khi bạn tái cấu trúc.

  • MultiCell() trả về 1, Write() trả về 0. Đây là các giá trị giữ chỗ tương thích, không phải giá trị được tính toán. Hãy điều chỉnh bất kỳ đoạn mã nào rẽ nhánh dựa trên các giá trị trả về đó.
  • Error() ném ngoại lệ thay vì gọi die(). Bộ chuyển đổi phát ra RuntimeException. Mã dựa vào việc tiến trình kết thúc phải bắt ngoại lệ này.
  • Các tham số bị bỏ qua âm thầm. Các phương thức như Image(), writeHTML(), SetProtection(), và Bookmark() nhận các tham số cũ bị bỏ qua. Hãy dùng chế độ nghiêm ngặt để tìm chúng. Để có một hình ảnh có thể bấm, hãy vẽ hình ảnh, rồi thêm Document::link() trên cùng hình chữ nhật đó.
  • Các phương thức chưa hiện thực. setSignature(), addEmptySignatureAppearance(), và endPage() là các no-op ném ngoại lệ trong chế độ nghiêm ngặt; Open() là một no-op an toàn không bao giờ ném ngoại lệ. Hãy gỡ bỏ endPage()Open(). Thao tác ký yêu cầu một phiên bản NextPDF thương mại thông qua API chữ ký hiện đại.
  • Phiên bản PDF là cố định. setPDFVersion() không thể hạ mục tiêu xuống một phiên bản PDF cũ hơn; kết quả luôn là PDF 2.0. setUserRights() đã không còn dùng trong PDF 2.0 và bị bỏ qua kèm một thông báo.
  • Xung đột bí danh. Nếu vẫn còn thứ gì đó phân giải tới lớp TCPDF thật sau khi bạn gỡ tecnickcom/tcpdf, lưu ý về bí danh sẽ áp dụng — hãy import bộ chuyển đổi một cách tường minh tại các nơi gọi đó.

Bộ chuyển đổi ủy thác cho công cụ; chi phí dựng tài liệu tỉ lệ với nội dung, không phải với lớp chuyển đổi. Vì Output() của bộ chuyển đổi không ghi vào bộ đệm xuất, nó an toàn bên trong một queue worker — hãy đưa các tác vụ tạo tài liệu nặng kiểu TCPDF ra khỏi luồng yêu cầu, giống như cách bạn xử lý bất kỳ tác vụ tạo NextPDF nào. Việc tạo lại chuẩn so sánh cho các bài kiểm thử cấp byte dựa trên nội dung được kết xuất là một chi phí một lần, và nó mang lại cho bạn các bài kiểm thử tồn tại qua các lần nâng cấp công cụ trong tương lai.

  • Mã hóa. SetProtection() bỏ qua các tham số cũ modepubkeys; công cụ dùng AES-256 cho handler tiêu chuẩn. Đối với mã hóa dựa trên chứng chỉ, hãy dùng điểm vào mã hóa khóa công khai hiện đại được phơi bày trên bộ chuyển đổi, thay vì dùng các tham số cũ.
  • Việc ký bị giới hạn theo phiên bản. Hỗ trợ chữ ký cơ bản là một khả năng của phiên bản thương mại, đạt được thông qua API chữ ký hiện đại với một đối tượng giá trị chứng chỉ; hàm cũ setSignature() là một no-op. Hướng dẫn này không tuyên bố gì về các hồ sơ chữ ký xác thực dài hạn hoặc có dấu thời gian cho bất kỳ phiên bản nào.
  • Hãy thất bại một cách tường minh trong lúc kiểm toán. Chế độ nghiêm ngặt làm rõ mọi trường hợp mất tham số âm thầm, nên bạn biết khi nào bộ chuyển đổi không tôn trọng ý định của bên gọi. Hãy xem các ngoại lệ thu thập được như danh sách công việc di chuyển, không phải như hành vi sản xuất.
  • Đừng bao giờ viết một khối catch rỗng. Ví dụ kiểm toán bắt TcpdfNotImplementedException và ghi ra một dòng xác định hạng mục công việc.

Lập trường đầy đủ về mã hóa và chữ ký trong lúc di chuyển nằm trong trang bảo mật và vận hành của compat-legacy.

Hướng dẫn này không đưa ra tuyên bố tiêu chuẩn quy phạm nào của riêng nó. Bộ chuyển đổi tạo kết quả PDF 2.0 (ISO 32000-2) và không thể hạ mục tiêu xuống một phiên bản cũ hơn. Hành vi đó và điều khoản liên quan được ghi rõ trên trang phạm vi phương thức ở thượng nguồn, trang này cũng ghi lại nguyên tắc thất bại tường minh của OWASP đứng sau chế độ nghiêm ngặt và khung tính đầy đủ chức năng theo ISO/IEC 25023 của lượt kiểm toán phạm vi. Trang cookbook này trình bày lại cách dùng và nhường các trích dẫn đó cho trang ở thượng nguồn.