เอนจินเดียว ทุกเฟรมเวิร์ก
Spec: PSR-11 Container, §1.1.2PSR-11 Container §1.1.2Spec: PSR-4 Autoloader, §3PSR-4 Autoloader §3
ภาพรวมโดยสังเขป
หัวข้อที่มีชื่อว่า “ภาพรวมโดยสังเขป”ฐานระบบ PHP ที่เติบโตขึ้นส่วนใหญ่ลงเอยด้วยการมีเฟรมเวิร์กมากกว่าหนึ่งตัว NextPDF เป็นเอนจิน PDF เดียวที่เข้าหาแต่ละตัวตามเงื่อนไขของมันเอง คือมีบริดจ์ตามสำนวนสำหรับ Laravel, Symfony และ CodeIgniter รวมถึงเส้นทางแบบสแตนด์อะโลนสำหรับโค้ดที่ไม่ได้รันในตัวใดเลย โมเดลเอกสารใช้ร่วมกัน มีเพียงวิธีที่คุณเรียกใช้มันเท่านั้นที่เปลี่ยน
เหตุใดเรื่องนี้จึงสำคัญ
หัวข้อที่มีชื่อว่า “เหตุใดเรื่องนี้จึงสำคัญ”การใช้ไลบรารี PDF ต่างกันต่อหนึ่งสแตกคือภาษีที่จ่ายอย่างเงียบๆ แต่ละตัวมีลักษณะเฉพาะของมันเอง มีการจัดการฟอนต์ของมันเอง มีแนวคิดของมันเองว่าอะไรคือความถูกต้อง ใบแจ้งหนี้ที่เรนเดอร์ออกมาถูกต้องจากเซอร์วิส Laravel อาจเรนเดอร์ออกมาต่างกันเพียงเล็กน้อยจากเวิร์กเกอร์ Symfony เพราะไลบรารีคนละตัววาดมัน ทีนี้เป้าหมายการจัดเก็บถาวร ตำแหน่งลายเซ็น และแท็กการเข้าถึงของคุณก็ขึ้นอยู่กับว่าทีมไหนเป็นคนส่งเอกสารนั้นออกไป รายงานบั๊กบอกว่า “PDF ผิด” และคำตอบขึ้นอยู่กับว่าเอนจินตัวไหนในสามตัวเป็นคนสร้างมัน
การยึดมาตรฐานไว้ที่เอนจินเดียวจะยุบพื้นผิวนั้นลง มีจุดเดียวที่โปรไฟล์ PDF/A ถูกตัดสิน มีไปป์ไลน์ฟอนต์เดียวที่ต้องรับรอง มีผู้ตรวจสอบความถูกต้องเดียวที่ต้องไว้ใจ เฟรมเวิร์กที่คุณบังเอิญอยู่ในนั้นเลิกเป็นตัวแปรในเรื่องว่าเอกสารถูกต้องหรือไม่
ฉบับย่อ
หัวข้อที่มีชื่อว่า “ฉบับย่อ”- เอนจินแกนหลักไม่ผูกกับเฟรมเวิร์ก
nextpdf/coreไม่รู้อะไรเลยเกี่ยวกับ HTTP, การกำหนดเส้นทาง หรือการเดินสายคอนเทนเนอร์ มันเป็นเอนจิน PDF 2.0 และไม่ใช่อะไรนอกเหนือจากนั้น - บริดจ์แต่ละตัวปรับให้เข้ากัน มันไม่ได้สร้างใหม่ แพ็กเกจ Laravel, Symfony และ CodeIgniter มอบฟาซาดหรือแฟกตอรี ตัวช่วยสำหรับการตอบสนอง HTTP และเส้นทางการสร้างแบบเข้าคิวหรือแบบไม่ประสานเวลา — บนเอนจินตัวเดียวกัน
- บริดจ์ตามเฟรมเวิร์กของคุณ ไม่ใช่ตามเอกสารของคุณ มันเปลี่ยนวิธีที่คุณเรียกเอนจิน ไม่เคยเปลี่ยนสิ่งที่เอนจินสร้างได้
- สแตนด์อะโลนมีให้ใช้เสมอ เครื่องมือ CLI, ดีมอน หรือไลบรารี ไม่มีเฟรมเวิร์กให้เชื่อมจากมัน มันสร้างเอกสารโดยตรง
- โมเดลเอกสารหนึ่งเดียวเดินทางข้ามทั้งสี่ ออบเจกต์ค่า อีนัม และสัญญาเอาต์พุตเดียวกันปรากฏอยู่ทุกที่ ดังนั้นเอกสารจึงเคลื่อนย้ายระหว่างจุดเรียกใช้ได้โดยไม่เปลี่ยนแปลง
แนวทางของ NextPDF ในเรื่องนี้
หัวข้อที่มีชื่อว่า “แนวทางของ NextPDF ในเรื่องนี้”สถาปัตยกรรมคือการแยกอย่างจงใจ เอนจินคือสินทรัพย์ ส่วนบริดจ์เป็นอะแดปเตอร์บางๆ ที่พูดสำนวนของเฟรมเวิร์กหนึ่งตัว บริดจ์ลงทะเบียนเนมสเปซเล็กๆ ทับบนแกนหลักที่ใช้ร่วมกันผ่านการโหลดอัตโนมัติมาตรฐาน (Spec: PSR-4 Autoloader, §3PSR-4 Autoloader §3) และส่งเอกสารกลับผ่านสัญญาคอนเทนเนอร์ (Spec: PSR-11 Container, §1.1.2PSR-11 Container §1.1.2) สัญญานั้นคือพระเอกเงียบในที่นี้ คือมันยอมให้การแก้ค่าตัวระบุเดียวกันสองครั้งส่งคืนอินสแตนซ์ต่างกัน ซึ่งเป็นวิธีที่บริดจ์มอบเอกสารใหม่ที่ใช้แล้วทิ้งให้คุณต่อหนึ่งคำขอ ขณะที่ยังคงเก็บรีจิสทรีฟอนต์ที่แจงแล้วและแคชรูปภาพไว้เป็นซิงเกิลตันระดับโพรเซส เวิร์กเกอร์ที่อยู่ยาว — Octane, RoadRunner, Swoole, Messenger — ได้การแจงฟอนต์แบบเฉลี่ยต้นทุนโดยไม่มีสถานะรั่วข้ามคำขอ ด้วยการออกแบบ
สี่สำนวนต่างกันที่พื้นผิวเท่านั้น
- Core enginenextpdf/core — the framework-agnostic PDF 2.0 engine; the single shared document model, value objects, and output contract.
- Laravel bridgenextpdf/laravel — auto-discovered provider, a Pdf facade, a PdfResponse helper, and a queued GeneratePdfJob.
- Symfony bridgenextpdf/symfony — an auto-registered bundle, an injectable PdfFactory, a PdfResponse, and an optional Messenger handler.
- CodeIgniter bridgenextpdf/codeigniter — a service and pdf() helper, a Pdf library over a disposable Document, and a PdfResponse.
- StandaloneNo framework to bridge from — construct a Document directly in a CLI tool, daemon, or library.
อ่านไดอะแกรมจากซ้ายไปขวาแล้วบทเรียนคือความสมมาตร ทุกพื้นผิวแก้ค่าไปสู่ Document ตัวเดียวกัน ฟาซาด Laravel, แฟกตอรี Symfony, เซอร์วิส CodeIgniter และตัวสร้างแบบสแตนด์อะโลนคือสี่ประตูสู่ห้องเดียวกัน
ตัวอย่างเชิงปฏิบัติ
หัวข้อที่มีชื่อว่า “ตัวอย่างเชิงปฏิบัติ”เจตนาสามบรรทัดเดียวกัน แสดงในแต่ละสำนวน ส่วนเนื้อหาที่สร้างเอกสาร — หน้า ฟอนต์ เซลล์ การลงนาม ความสอดคล้อง — เหมือนกันทั้งสี่ เพราะมันคือเอนจินตัวเดียวกัน
<?php
declare(strict_types=1);
// Laravel — resolve a fresh document from the container.use NextPDF\Contracts\PdfDocumentInterface;$document = app(PdfDocumentInterface::class);
// Symfony — inject the factory, then ask it for a document.use NextPDF\Symfony\Service\PdfFactory;$document = $factory->create(); // PdfFactory injected into your service
// CodeIgniter — pull it from the Services layer.use NextPDF\CodeIgniter\Config\Services;$document = Services::pdfDocument();
// Standalone — no framework; construct it directly.use NextPDF\Core\Document;$document = Document::createStandalone();
// From here, the code is identical regardless of how $document arrived.$document->addPage();$document->cell(0, 10, 'One engine, every framework', newLine: true);$bytes = $document->getPdfData();บรรทัดแรกคือความแตกต่างเพียงอย่างเดียว ทุกอย่างหลังจากนั้นย้ายที่ได้ คือย้ายเซอร์วิสที่สร้างเอกสารจาก Symfony ไปยังเวิร์กเกอร์แบบสแตนด์อะโลน แล้วโค้ดการเรนเดอร์ก็ไม่เปลี่ยน เพราะสัญญาที่มันพึ่งพาไม่ได้เปลี่ยน
ความเข้าใจผิดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ความเข้าใจผิดที่พบบ่อย”ข้อสันนิษฐานที่พบบ่อยคือบริดจ์ของเฟรมเวิร์กปลดล็อกความสามารถ — ว่าการตรวจสอบความถูกต้องของลายเซ็นระยะยาวหรือใบแจ้งหนี้อิเล็กทรอนิกส์ที่มีโครงสร้างมาถึงเพราะคุณติดตั้ง nextpdf/laravel แทนที่จะเรียกเอนจินโดยตรง มันไม่ใช่เช่นนั้น บริดจ์เปลี่ยนจุดเรียกใช้ ไม่เคยเปลี่ยนขอบเขตของเอนจิน ความสามารถแกนหลักเช่นเอาต์พุต PDF/A และการลงนามพื้นฐาน PAdES เป็นโอเพนซอร์สและไปถึงทุกพื้นผิว ส่วนความสามารถขั้นสูงถูกปลดล็อกโดยรุ่น และจากนั้นก็มีให้ใช้ ผ่าน บริดจ์ใดก็ได้หรือเส้นทางสแตนด์อะโลนเท่าเทียมกัน การเลือกการผสานรวมเฟรมเวิร์กไม่ใช่การเลือกชุดฟีเจอร์
ความเข้าใจผิดในกระจกเงาคือ “เอนจินเดียว” ต้องหมายถึงเส้นทางการเรนเดอร์เดียวสำหรับทุกเอกสาร มันไม่ใช่เช่นนั้น เอนจินในโพรเซสเรนเดอร์ PDF โดยตรง เมื่อเอกสารจำเป็นต้องใช้เอนจินจัดวางระดับเบราว์เซอร์จริงๆ แพ็กเกจตัวเรนเดอร์จะจัดการเรื่องนั้น การเรนเดอร์และการเรียกใช้เป็นคนละแกนกัน — คู่มือการตัดสินใจผสานรวม คือที่ที่ทำแผนที่ทั้งสองนั้น
ข้อจำกัดและขอบเขต
หัวข้อที่มีชื่อว่า “ข้อจำกัดและขอบเขต”บริดจ์ไม่ได้ขยายสิ่งที่เอนจินเรนเดอร์ได้ นั่นคือขีดจำกัดที่ซื่อตรง และมันคือประเด็น คือความสามารถอยู่ในแกนหลักและในระดับชั้น ไม่ใช่ในอะแดปเตอร์ที่คุณเข้าถึงมันผ่าน
| Edition | Availability |
|---|---|
| Core | ทุกบริดจ์ (Laravel, Symfony, CodeIgniter) และเส้นทางสแตนด์อะโลนเป็น Apache-2.0 และทำงานกับ Core พวกมันปรับหรือเปิดเผยเอนจิน พวกมันไม่ได้กั้น ฟีเจอร์และไม่ได้เปลี่ยนสิ่งที่มันสร้างได้ |
| Pro | ความสามารถขั้นสูงเช่นการตรวจสอบความถูกต้องของลายเซ็นระยะยาว (PAdES B-LT และ B-LTA) ถูกปลดล็อกโดยรุ่น แล้วเข้าถึงได้เหมือนกันผ่านบริดจ์ใดก็ได้หรือ สแตนด์อะโลน — ไม่เคยผ่านการสลับเฟรมเวิร์ก เอาต์พุต PDF/A สำหรับการจัดเก็บถาวร และการลงนามพื้นฐาน PAdES (B-B และ B-T) อยู่ใน Core อยู่แล้ว เข้าถึงได้ในแบบ เดียวกันผ่านทุกพื้นผิว |
| Enterprise | ใบแจ้งหนี้อิเล็กทรอนิกส์ที่มีโครงสร้าง (EN 16931) และเครื่องมือด้านความ สอดคล้องที่ลึกกว่าก็เป็นความสามารถของรุ่นเช่นกัน เหมือนกันไม่ว่าพื้นผิวใดเรียก เอนจิน ขณะที่การตรวจสอบความสอดคล้องเองมาพร้อม Core |
มีอีกสองขอบเขตที่ควรระบุให้ชัด ประการแรก บริดจ์แต่ละตัวติดตามเมเจอร์ปัจจุบันของเฟรมเวิร์กของมัน — Laravel, Symfony และ CodeIgniter ต่างกำหนดช่วงที่รองรับ ดังนั้น “ทุกเฟรมเวิร์ก” จึงหมายถึงเวอร์ชันที่รองรับของแต่ละตัว ไม่ใช่ทุกรุ่นในประวัติศาสตร์ จงถือเอกสารของแต่ละแพ็กเกจเองเป็นแหล่งอ้างอิงที่เชื่อถือได้สำหรับ API ของมัน ประการที่สอง บริดจ์เป็นอะแดปเตอร์ของเฟรมเวิร์ก ไม่ใช่แบ็กเอนด์การเรนเดอร์ หากเอกสารจำเป็นต้องใช้เอนจินจัดวางเบราว์เซอร์เต็มรูปแบบ นั่นเป็นการเลือกตัวเรนเดอร์ที่เป็นอิสระจากว่าเฟรมเวิร์กใดเรียกเอนจิน
เอกสารที่เกี่ยวข้อง
หัวข้อที่มีชื่อว่า “เอกสารที่เกี่ยวข้อง”- คู่มือการตัดสินใจผสานรวม — แผนที่จากกรณีใช้งานสู่แพ็กเกจ รวมถึงตัวเรนเดอร์และพื้นผิวเซอร์วิส Connect เมื่อคุณต้องการตัดสินใจมากกว่าจะยึดมาตรฐาน
- แกนเปิด ไม่มีการผูกมัด — ทำไมเอนจินจึงเป็นสินทรัพย์และบริดจ์จึงบาง ดังนั้นการยึดมาตรฐานจึงไม่กักขังคุณ
- ไปป์ไลน์ HTML — สิ่งที่เอนจินในโพรเซสครอบคลุม เพื่อให้คุณรู้ว่าเมื่อใดที่ตัวเรนเดอร์เบราว์เซอร์เป็นคำถามที่แยกต่างหาก
- รากฐาน PHP 8.4 — พื้นรันไทม์ที่ทุกบริดจ์และเส้นทางสแตนด์อะโลนใช้ร่วมกัน
อภิธานศัพท์
หัวข้อที่มีชื่อว่า “อภิธานศัพท์”- เอนจินแกนหลัก (Core engine) —
nextpdf/coreคือเอนจิน PDF 2.0 ที่ไม่ผูกกับเฟรมเวิร์กซึ่งทุกบริดจ์และเส้นทางสแตนด์อะโลนสร้างต่อยอด - บริดจ์ของเฟรมเวิร์ก (Framework bridge) — แพ็กเกจการผสานรวม (Laravel, Symfony, CodeIgniter) ที่ปรับเอนจินให้เข้ากับสำนวนของเฟรมเวิร์ก — ฟาซาด แฟกตอรี การตอบสนอง งานเข้าคิว — โดยไม่เปลี่ยนความสามารถของมัน
- เส้นทางสแตนด์อะโลน (Standalone path) — การใช้เอนจินแกนหลักโดยตรง โดยไม่มีเฟรมเวิร์ก ด้วยการสร้าง
Documentด้วยตัวคุณเอง คือเส้นทางสำหรับเครื่องมือ CLI, ดีมอน และไลบรารี - เอกสารแบบใช้แล้วทิ้ง (Disposable document) — สัญญา
Documentที่ใช้ครั้งเดียว คือสร้าง ปล่อยออก ทิ้ง การแก้ค่าคอนเทนเนอร์แต่ละครั้งส่งคืนตัวใหม่ ดังนั้นจึงไม่มีสถานะรั่วระหว่างคำขอในเวิร์กเกอร์ที่อยู่ยาว - PAdES — PDF Advanced Electronic Signatures คือตระกูลโปรไฟล์ ETSI สำหรับการลงนาม PDF การลงนามพื้นฐาน (B-B และ B-T) อยู่ใน Core ส่วนการตรวจสอบความถูกต้องระยะยาว (B-LT และ B-LTA) เป็นความสามารถของรุ่นขั้นสูง ทั้งสองเข้าถึงได้ผ่านพื้นผิวใดก็ได้ ซึ่งกล่าวถึงเชิงลึกในหน้าการลงนาม