ข้ามไปยังเนื้อหา
getnextpdf.com

การย้ายออกจากไลบรารีเดิม: TCPDF, FPDF และพวกพ้อง

Spec: ISO 32000-2Spec: ISO 19005-4Spec: ETSI EN 319 142-1

หาก PDF ของคุณถูกสร้างขึ้นด้วย TCPDF, FPDF, mPDF หรือ dompdf โค้ดนั้นก็มักจะยังคงทำงานได้ และนั่นเองคือเหตุผลที่ทำให้ปัญหาถูกมองข้ามได้ง่าย ไลบรารียังทำงานอยู่ ไฟล์ยังเปิดได้ และช่องว่างจะปรากฏให้เห็นก็ต่อเมื่อถึงวันที่มีคนขอเอกสารที่ลงนาม จัดเก็บถาวรได้ หรือเข้าถึงได้ แล้วคำตอบกลับเป็น “เราทำจากตรงนี้ไม่ได้”

หน้านี้คือเรื่องราวของการย้ายระบบ ว่าทางตันเหล่านั้นคืออะไร เหตุใดจึงเป็นปัญหาเชิงโครงสร้างไม่ใช่เรื่องบังเอิญ และ NextPDF มอบเส้นทางออกแบบเป็นขั้นเป็นตอนให้คุณได้อย่างไร — รวมถึงพื้นผิวความเข้ากันได้กับ TCPDF ที่เป็นตัวช่วยในการย้ายระบบ ไม่ใช่คำมั่นว่าจะเป็น drop-in แบบ byte-identical

ไลบรารี PDF ไม่ใช่การเรียกเรนเดอร์ที่คุณทำเพียงครั้งเดียว แต่เป็น dependency ที่เอกสารของคุณสืบทอดไปตลอดตราบเท่าที่เอกสารนั้นยังคงอยู่ เมื่อ dependency นั้นหยุดเคลื่อนไหว เอกสารของคุณก็หมดความสามารถที่จะทำสิ่งใหม่ๆ — และคุณจะรู้ตัวในวินาทีที่เลวร้ายที่สุด คือเมื่อลูกค้า ผู้ตรวจสอบ หรือหน่วยงานกำกับดูแลตั้งมาตรฐานขึ้นมา

ทางตันเหล่านั้นมีลักษณะดังนี้ รูปแบบของมาตรฐานเดินหน้าไปแล้ว: PDF 2.0 คือฉบับปัจจุบันของมาตรฐาน (Spec: ISO 32000-2) และ writer ที่ติดอยู่กับโครงสร้าง 1.x ก็ตามหลังรูปแบบที่ส่วนอื่นของ toolchain ของคุณคาดหมายไว้แล้ว การลงนามนั้นบางหรือถูกต่อเติมเข้ามาทีหลัง ห่างไกลจากโปรไฟล์เบสไลน์ของ PAdES ที่ทำให้ลายเซ็นยืนหยัดได้ (Spec: ETSI EN 319 142-1, §4) ส่วนเอาต์พุตเพื่อการจัดเก็บถาวรไปยังตระกูล PDF/A และโครงสร้างแบบ tagged เพื่อการเข้าถึง ก็ไม่มีหรือเปราะบาง และตัว API เองก็ไร้ type — แนวการวางหน้าเป็น string ค่า boolean แบบกำหนดตามตำแหน่ง ค่าเริ่มต้นที่คุณค้นพบโดยบังเอิญ — ดังนั้น compiler จึงช่วยคุณไม่ได้ และผู้รีวิวก็เช่นกัน

สิ่งเหล่านี้ไม่มีอันใดที่เป็นบั๊กที่คุณจะ patch แก้ไขข้ามไปได้ แต่มันคือรูปทรงของเครื่องมือที่ถูกสร้างขึ้นมาเพื่อยุคก่อนหน้า และเครื่องมือเหล่านั้นหลายตัวก็ไม่ได้เคลื่อนไหวเข้าหามาตรฐานที่เอกสารของคุณต้องปฏิบัติตามในตอนนี้อย่างจริงจังอีกต่อไป

  • ไลบรารี PDF ของ PHP รุ่นเดิมส่วนใหญ่ยัง ทำงาน ได้ ปัญหาอยู่ที่สิ่งที่มัน โดยทั่วไปไม่สามารถสร้างได้ด้วยความสอดคล้องสมัยใหม่อย่างครบถ้วน: PDF 2.0 ลายเซ็นที่สอดคล้องกับเบสไลน์ PDF/A ที่ผ่านการตรวจสอบ การเข้าถึงแบบ tagged — การรองรับในไลบรารีที่ระบุชื่อมาเหล่านั้นมีอยู่อย่างจำกัดหรือไม่มีเลย
  • NextPDF เป็นเอนจิน PHP 8.4 ที่เขียน PDF 2.0 เป็นค่าเริ่มต้น พร้อมด้วย type ที่ เคร่งครัด โปรไฟล์การจัดเก็บถาวร และการลงนามแบบ PAdES ในฐานะเอาต์พุตชั้นหนึ่ง
  • คุณไม่จำเป็นต้องเขียนใหม่ทั้งหมดตั้งแต่วันแรก พื้นผิวความเข้ากันได้กับ TCPDF ทำให้การเรียกที่คุ้นเคยยังทำงานต่อไปได้ในขณะที่คุณย้าย logic ของ เอกสารที่สำคัญ
  • พื้นผิวนั้น เข้ากันได้กับ TCPDF แต่ไม่ใช่ byte-identical มันคือสะพานเชื่อม ตลอดการย้ายระบบ พร้อมความแตกต่างเชิงพฤติกรรมที่บันทึกไว้ — ไม่ใช่การกล่าวอ้าง ว่าทุกสคริปต์จะทำงานได้โดยไม่ต้องแก้ไข
  • การทดสอบที่ซื่อตรงคือดูว่าความสามารถใหม่ๆคุ้มค่ากับการย้ายหรือไม่ สำหรับภาระงาน บางอย่างนั้นไม่คุ้ม และเราก็พูดเช่นนั้นอย่างตรงไปตรงมา

แนวทางคือการทำให้การย้ายระบบเป็นลำดับขั้น ไม่ใช่การกระโดดข้าม คุณยังคงสร้างเอกสารได้ตลอดทาง และคุณแลกข้อจำกัดเก่าออกไปทีละอย่าง แทนที่จะเดิมพันทั้งรีลีสไปกับการเขียนใหม่แบบ big-bang

  1. InventoryCatalogue what your documents actually need to emit — signatures, archival profiles, tagged structure, fonts — not just which calls you make today.
  2. BridgeAdopt the TCPDF-compatibility surface so the existing call sites keep producing files while the engine underneath becomes NextPDF.
  3. PortMove the document logic that matters onto the native typed API, where intent is explicit and the compiler checks it.
  4. UpgradeTurn on the outputs many legacy libraries cannot reach with full modern conformance: PDF 2.0 structure, validated PDF/A, PAdES signatures, tagged accessibility.
  5. VerifyConfirm the result against a real validator, so 'archival' or 'signed' means a tool agrees, not just that the file opened.
A staged migration off a legacy PDF library: start on the compatibility surface so existing calls keep working, then move document logic onto the typed native API, then turn on the standards-grade outputs (PDF 2.0, PDF/A, PAdES, accessibility) that many legacy libraries cannot produce with full modern conformance.

PDF 2.0 คือเบสไลน์ ไม่ใช่ feature flag NextPDF เขียนฉบับปัจจุบันของรูปแบบเป็นค่าเริ่มต้น (Spec: ISO 32000-2) และสามารถ serialize โครงสร้างเก่ากว่าได้เมื่อโปรไฟล์ร้องขอ ไลบรารีที่ถูกแช่แข็งไว้กับโครงสร้าง 1.x ไม่สามารถมาพบคุณ ณ จุดนี้ได้ มันไม่ใช่การตั้งค่าที่มันลืมไป แต่มันคือยุคสมัยที่มันมีมาก่อน

การจัดเก็บถาวรและการเข้าถึงเป็นคุณสมบัติของ writer การสร้างไฟล์ที่ validator ยอมรับว่าเป็น PDF/A คือสิ่งที่เอนจินต้องทำในขณะที่มันเขียน — ไม่สามารถนำมาแปะติดทีหลังได้ (Spec: ISO 19005-4) เช่นเดียวกันกับโครงสร้างแบบ tagged ที่ทำให้ PDF เข้าถึงได้ NextPDF สร้างสิ่งเหล่านี้ขึ้นในระหว่างการสร้างเอกสาร ซึ่งเป็นขั้นตอนที่เครื่องมือรุ่นเดิมหลายตัวทำไม่ได้ — หรือทำได้เพียงบางส่วน ไม่ถึงระดับที่ validator ยอมรับ

การลงนามผ่านมาตรฐานเบสไลน์ ลายเซ็นอิเล็กทรอนิกส์ขั้นสูงใน PDF เป็นไปตามโปรไฟล์ PAdES (Spec: ETSI EN 319 142-1, §4) ที่ digest ครอบคลุมช่วงไบต์ที่ประกาศไว้ และลายเซ็นพกพา metadata ที่ validator ตรวจสอบ ตัวช่วยลงนามที่ต่อเติมเข้ามาทีหลังนั้นแทบไม่เคยไปถึงมาตรฐานนั้น NextPDF ปฏิบัติต่อมันในฐานะเอาต์พุตชั้นหนึ่ง ไม่ใช่สิ่งที่นึกขึ้นได้ทีหลัง

พื้นผิวความเข้ากันได้คือสะพานเชื่อม ที่กล่าวไว้อย่างซื่อตรง เลเยอร์ TCPDF-compat มีอยู่เพื่อให้จุดเรียกที่มีอยู่เดิมยังคงสร้างเอกสารต่อไปได้ในขณะที่คุณย้ายส่วนที่สำคัญ มันเป็นไปตามแบบจำลองเดียวกับคู่มือการย้ายระบบทุกฉบับของ NextPDF: เข้ากันได้กับไลบรารีต้นทาง แต่ไม่ใช่ byte-identical พร้อมความแตกต่างเชิงพฤติกรรมที่เขียนไว้ ความซื่อตรงนั้นคือหัวใจ — การกล่าวอ้างแบบเงียบๆว่าเป็น “drop-in 99%” คือชนิดของการเดาที่เอนจินนี้ถูกสร้างขึ้นมาเพื่อปฏิเสธ

รูปทรงของการย้ายระบบนั้นเล็กน้อยที่จุดเรียก โค้ดเดิมยังคงสร้างไฟล์ผ่านพื้นผิวความเข้ากันได้ ส่วนโค้ดใหม่ระบุเจตนาผ่าน API เนทีฟแบบมี type และร้องขอเอาต์พุตที่ไลบรารีรุ่นเดิมไปไม่ถึง หรือไปถึงได้ด้วยความสอดคล้องที่จำกัด

<?php
declare(strict_types=1);
use NextPDF\Compat\Tcpdf\TCPDF;
use NextPDF\Contracts\Orientation;
use NextPDF\Contracts\OutputDestination;
use NextPDF\Core\Document;
use NextPDF\ValueObjects\PageSize;
// 1) The bridge: a familiar TCPDF-shaped call keeps producing a file
// while the engine underneath is already NextPDF. Behaviour is
// compatible, not byte-identical — differences are documented.
$legacy = new TCPDF();
$legacy->AddPage();
$legacy->SetFont('helvetica', 'B', 16);
$legacy->Cell(0, 12, 'Migrated invoice', ln: 1);
$bridgedBytes = $legacy->Output('', 'S');
// 2) The destination: the same document expressed natively, where intent
// is typed and the engine can emit what many legacy tools cannot.
$document = Document::createStandalone();
$document->setTitle('Migrated invoice');
$document->addPage(PageSize::a4(), Orientation::Portrait);
$document->setFont('helvetica', 'B', 16);
$document->cell(0, 12, 'Migrated invoice', newLine: true);
// Bytes only, no HTTP headers, no file side effect — stated, not inferred.
$nativeBytes = $document->output(dest: OutputDestination::String);

บล็อกแรกคือจุดยึดเกาะ: ไม่มีสิ่งใดในแอปพลิเคชันของคุณที่ต้องเปลี่ยนเพื่อให้เอกสารไหลต่อไปได้ ส่วนบล็อกที่สองคือปลายทาง: การเรียกแบบมี type ที่ “portrait” “string output” และฟอนต์ถูกระบุอย่างชัดเจน และที่การจัดเก็บถาวร การลงนาม และการเข้าถึงกลายเป็นเอาต์พุตที่คุณสามารถเปิดใช้งานได้ แทนที่จะเป็นทางตันที่คุณวิ่งชน

ความหวังที่พบบ่อยคือ “มันต้องมี flag ที่ทำให้ไลบรารีเก่าของฉันทำ PDF 2.0 และลายเซ็นได้สิ” แต่ไม่มี สิ่งเหล่านี้ไม่ใช่ตัวเลือกที่ไลบรารีที่สมบูรณ์แล้วลืมเปิดเผยออกมา แต่มันคือความสามารถที่สถาปัตยกรรมของมันไม่เคยถูกสร้างขึ้นมาให้รองรับเลย คุณไม่สามารถปรับการตั้งค่าเพื่อให้ได้ฉบับของรูปแบบ หรือโปรไฟล์ลายเซ็นที่ writer ไม่ได้นำไปใช้งานได้

ความเข้าใจผิดในด้านตรงข้ามคือการคิดว่า NextPDF เป็น drop-in ของ TCPDF แบบ 100% ดังนั้นการย้ายระบบจึงไม่มีต้นทุน มันไม่เป็นเช่นนั้น และเราจะไม่แสร้งเป็นอื่น พื้นผิวความเข้ากันได้ครอบคลุมส่วนหนึ่งของ API ที่มีอยู่จริงและบันทึกไว้เพื่อพาคุณข้ามการย้ายระบบ บางการเรียกมีพฤติกรรมต่างออกไป และบางส่วนอยู่นอกขอบเขต จงปฏิบัติต่อมันในฐานะสะพานเชื่อมที่มีแผนที่เผยแพร่ไว้ ไม่ใช่การรับประกันว่าทุกสคริปต์รุ่นเดิมจะทำงานได้โดยไม่ถูกแตะต้อง

TCPDF-compatibility surface as a migration aid — edition availability
EditionAvailability
Core

พื้นผิวความเข้ากันได้นั้น เข้ากันได้กับ TCPDF แต่ไม่ใช่ byte-identical มันครอบคลุมชุดย่อยของ API ที่บันทึกไว้เพื่อให้จุดเรียกที่มีอยู่เดิมยังคงสร้าง ไฟล์ได้ในระหว่างการย้ายระบบ มันคือสะพานเชื่อม ไม่ใช่ drop-in: บางพฤติกรรม ต่างออกไปและบางการเรียกไม่รองรับ ซึ่งทั้งหมดระบุไว้ในหน้าความครอบคลุมของ method และหน้าการย้ายระบบ ปลายทางคือ API เนทีฟแบบมี type ซึ่งเป็นที่อยู่ของ เอาต์พุตระดับมาตรฐาน

ProAvailable
EnterpriseAvailable

การย้ายระบบเป็นวิธีการ ไม่ใช่คุณธรรม หากเอกสารของคุณเรียบง่าย ไลบรารีของคุณยังได้รับการดูแล และคุณจะไม่มีวันต้องใช้ PDF 2.0 การลงนาม PDF/A หรือการเข้าถึง คำตอบที่ซื่อตรงอาจเป็นการอยู่ที่เดิม — ต้นทุนการเปลี่ยนนั้นมีอยู่จริง และการย้ายที่คุณไม่จำเป็นต้องทำคือการย้ายที่คุณไม่ควรทำ หน้าเรื่องเมื่อใดที่ไม่ควรใช้ NextPDF ขีดเส้นนั้นไว้โดยไม่หวั่นไหว

หน้านี้อธิบาย เส้นทาง ของการย้ายระบบและ เป้าหมาย ของเอนจิน ส่วนความครอบคลุมของ API ที่แน่นอน ความแตกต่างเชิงพฤติกรรม และขั้นตอนแบบทีละขั้นนั้นอยู่ในเอกสารความเข้ากันได้ ซึ่งเป็นแหล่งอ้างอิงสำหรับสิ่งที่แต่ละการเรียกทำ ไม่มีสิ่งใดในที่นี้ที่สัญญาว่าสคริปต์รุ่นเดิมตามอำเภอใจจะทำงานได้โดยไม่ต้องแก้ไข

  • PDF 2.0 — ฉบับปัจจุบันของมาตรฐาน Portable Document Format (ISO 32000-2) ขยายความเมื่อใช้งานครั้งแรก; รูปแบบที่ NextPDF เขียนเป็นค่าเริ่มต้น
  • PDF/A — ตระกูลความสอดคล้องเพื่อการจัดเก็บถาวร (ชุดมาตรฐาน ISO 19005) ที่ กำหนดว่าสิ่งใดทำให้ PDF ปลอดภัยต่อการเก็บรักษาในระยะยาว เป็นคุณสมบัติที่ writer ต้องสร้าง ไม่ใช่สิ่งที่ผู้เรียกเพิ่มเข้ามาทีหลังได้
  • PAdES — PDF Advanced Electronic Signatures ชุดโปรไฟล์ของ ETSI (EN 319 142) สำหรับการฝังลายเซ็นระดับมาตรฐานใน PDF ขยายความเมื่อใช้งาน ครั้งแรก; กล่าวถึงเชิงลึกในหน้าการลงนาม
  • พื้นผิวความเข้ากันได้ (Compatibility surface) — เลเยอร์ API ที่มีรูปทรง เหมือนไลบรารีต้นทาง (ในที่นี้คือ TCPDF) ที่ทำให้จุดเรียกที่มีอยู่เดิมยังทำงาน ได้ในระหว่างการย้ายระบบ เข้ากันได้กับต้นฉบับ แต่ไม่ใช่ byte-identical — เป็น สะพานเชื่อม ไม่ใช่ drop-in
  • Drop-in replacement — สิ่งทดแทนที่รันโค้ดเดิมได้โดยไม่ต้องแก้ไข พื้นผิว TCPDF-compat ตั้งใจ ไม่ อธิบายในลักษณะนี้; มันคือตัวช่วยในการย้ายระบบที่ บันทึกไว้พร้อมความแตกต่างเชิงพฤติกรรมที่ทราบกันอยู่