ภาพรวมการผสานการทำงาน NextPDF Laravel
ภาพรวมโดยสังเขป
หัวข้อที่มีชื่อว่า “ภาพรวมโดยสังเขป”แพ็กเกจ nextpdf/laravel เชื่อมต่อเอนจิน PDF ของ NextPDF เข้ากับแอปพลิเคชัน Laravel 12 และลงทะเบียน container binding ให้โดยอัตโนมัติ แพ็กเกจนี้มี facade Pdf ตัวช่วย HTTP PdfResponse และงานคิว GeneratePdfJob ระบบ package discovery ของ Laravel จะตรวจพบแพ็กเกจนี้โดยอัตโนมัติ จึงไม่จำเป็นต้องลงทะเบียนด้วยตนเอง
การติดตั้ง
หัวข้อที่มีชื่อว่า “การติดตั้ง”composer require nextpdf/laravelข้อกำหนดของ Composer ระบุ nextpdf/core: ^3.0 || ^5.2 แพ็กเกจนี้ยัง
ต้องใช้ laravel/framework: ^12.0 และ php: >=8.4 <9.0 ด้วย สำหรับขั้นตอนทั้งหมด รวมถึงการเผยแพร่การกำหนดค่าและส่วนขยายเสริม โปรดดู /integrations/laravel/install/
ภาพรวมเชิงแนวคิด
หัวข้อที่มีชื่อว่า “ภาพรวมเชิงแนวคิด”แพ็กเกจนี้ทำหน้าที่คั่นกลางระหว่าง service container ของ Laravel กับแกนหลัก NextPDF ที่เป็นอิสระจากเฟรมเวิร์ก แพ็กเกจนี้ไม่ได้สร้างกระบวนการสร้าง PDF ขึ้นใหม่ แต่ปรับโมเดล NextPDF\Core\Document ของแกนหลักให้เข้ากับวงจรชีวิต การกำหนดค่า คิว และเลเยอร์ HTTP ของ Laravel แทน
แผนภาพด้านล่างแสดงเส้นทางของคำขอจากโค้ดแอปพลิเคชัน ผ่านแพ็กเกจ ไปจนถึง registry ของแกนหลักที่ใช้ร่วมกัน
autoload map มีรายการ PSR-4 หนึ่งรายการ PSR-4 คือ PHP Standard Recommendation สำหรับ autoloading และคำนำหน้า NextPDF\Laravel\ จะแมปไปยัง src/Laravel/ ภายใต้ PSR-4 คำนำหน้า namespace จะชี้ไปยังไดเรกทอรีฐาน และชื่อคลาสส่วนที่เหลือจะแมปไปยังพาธไฟล์ภายใต้ไดเรกทอรีนั้น (PSR-4 §3) มีคลาสสำหรับใช้งานจริงสี่คลาสอยู่ภายใต้คำนำหน้านี้:
NextPDF\Laravel\NextPdfServiceProvider— ลงทะเบียน binding และเผยแพร่การกำหนดค่าNextPDF\Laravel\Facades\Pdf— static proxy ที่รีโซลฟ์เอกสารใหม่จาก containerNextPDF\Laravel\Http\PdfResponse— สร้าง PDF response แบบ inline แบบดาวน์โหลด และแบบสตรีม พร้อมชุด security header ที่กำหนดไว้คงที่NextPDF\Laravel\Jobs\GeneratePdfJob— งานที่เข้าคิวได้ ซึ่งสร้างและบันทึก PDF บน worker
service provider นี้ใช้ DeferrableProvider จึงลงทะเบียน binding เฉพาะเมื่อมีการรีโซลฟ์รายการใดรายการหนึ่งที่ประกาศไว้เท่านั้น การเลื่อนการลงทะเบียนนี้ช่วยให้ขั้นตอนเริ่มทำงานของเฟรมเวิร์กกระชับ เมท็อด provides() ของ provider จะแสดงรายการบริการที่เลื่อนการลงทะเบียนไว้ และ container จะอ่านรายการนี้เพื่อแมปแต่ละคีย์กลับไปยัง provider
การรีโซลฟ์เป็นไปตามสัญญาของ container: เมื่อมี binding อยู่ การรีโซลฟ์ตัวระบุจะคืนค่ารายการที่ลงทะเบียนไว้ PSR-11 คือ PHP Standard Recommendation สำหรับการทำงานร่วมกันของ container และระบุไว้ว่าการเรียก get() สองครั้งติดต่อกันด้วยตัวระบุเดียวกันอาจคืนค่าที่แตกต่างกัน ขึ้นอยู่กับกลยุทธ์ของ binding (PSR-11 §1.1.2) NextPDF อาศัยพฤติกรรมนี้อย่างจงใจ registry แต่ละรายการเป็น singleton การรีโซลฟ์แต่ละครั้งจึงคืนค่าอินสแตนซ์เดียวกัน เอกสารถูก bind แบบ factory การรีโซลฟ์แต่ละครั้งจึงคืนค่าอินสแตนซ์ใหม่ สำหรับตารางอายุการใช้งานของ binding ทั้งหมด โปรดดู /integrations/laravel/boot-and-discovery/
สถาปัตยกรรมนี้ออกแบบมาสำหรับ worker ที่มีอายุการใช้งานยาวนาน เช่น Octane, RoadRunner และ Swoole font registry เป็น singleton ระดับโพรเซส: แพ็กเกจจะอุ่นเครื่องเพียงครั้งเดียวแล้วล็อกไว้ จึงไม่มีคำขอใดเปลี่ยนแปลงสถานะฟอนต์ที่ใช้ร่วมกันได้ image registry เป็น singleton ระดับโพรเซส พร้อมแคชแบบ least-recently-used (LRU) ที่มีขอบเขตจำกัด เนื่องจากแพ็กเกจสร้างเอกสารแต่ละชุดจาก DocumentFactory เสมอ สถานะที่เปลี่ยนแปลงได้ต่อคำขอจึงไม่รั่วไหลข้ามคำขอ
ขอบเขต API
หัวข้อที่มีชื่อว่า “ขอบเขต API”| คลาส | จุดเข้าใช้งานสาธารณะ | ค่าที่คืน | วัตถุประสงค์ |
|---|---|---|---|
NextPdfServiceProvider | register(), boot(), provides() | void / array | container binding, การเผยแพร่ config, รายการบริการที่เลื่อนการลงทะเบียนไว้ |
Facades\Pdf | static proxy (addPage(), cell(), save(), …) | static / mixed | รีโซลฟ์ PdfDocumentInterface ในแต่ละการเรียก |
Http\PdfResponse | inline(), download(), streamInline(), streamDownload() | Response / StreamedResponse | HTTP response พร้อม header แบบ Open Worldwide Application Security Project (OWASP) |
Jobs\GeneratePdfJob | dispatch(), handle(), then(), catch(), failed() | PendingDispatch / void / self | การสร้าง PDF แบบเข้าคิว |
คีย์ container ที่ provider bind ไว้:
| คีย์ | อายุการใช้งาน | รีโซลฟ์ไปยัง |
|---|---|---|
NextPDF\Contracts\FontRegistryInterface (alias FontRegistry) | singleton, ล็อกไว้ | NextPDF\Typography\FontRegistry |
NextPDF\Graphics\ImageRegistry | singleton, จำกัดด้วย LRU | ImageRegistry |
NextPDF\Contracts\DocumentFactoryInterface (alias DocumentFactory) | singleton | NextPDF\Core\DocumentFactory |
Psr\Http\Client\ClientInterface | singleton | SecurityAwareHttpClient ที่ห่อหุ้ม CurlHttpClient |
NextPDF\Security\Timestamp\TsaClient | scoped | TsaClient หรือ null เมื่อไม่มี URL ของ timestamp authority (TSA) |
NextPDF\Contracts\SignerInterface | factory | DigitalSigner หรือ null เมื่อปิดใช้งานการลงนาม |
NextPDF\Contracts\PdfDocumentInterface (alias nextpdf) | factory | NextPDF\Core\Document |
NextPDF\Contracts\EInvoice\{Embedder,Validator,Profile,SchematronRunner}Interface | factory | รีโซลฟ์ได้เฉพาะเมื่อติดตั้ง nextpdf/premium เท่านั้น |
ตัวอย่างโค้ด — เริ่มต้นใช้งานอย่างรวดเร็ว
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — เริ่มต้นใช้งานอย่างรวดเร็ว”<?php
declare(strict_types=1);
use NextPDF\Laravel\Facades\Pdf;
Pdf::addPage();Pdf::cell(0, 10, 'Hello from Laravel', newLine: true);Pdf::save(storage_path('app/hello.pdf'));สำหรับตัวอย่างที่รันได้ภายใน controller โปรดดู /integrations/laravel/quickstart/
ตัวอย่างโค้ด — การใช้งานจริง
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — การใช้งานจริง”แนวทางสำหรับการใช้งานจริงจะรีโซลฟ์สัญญาเอกสารจาก container แทนการใช้ facade ซึ่งทำให้จุดที่เรียกใช้ชัดเจนและทดสอบได้ สำหรับ controller ฉบับเต็ม รวมถึง dependency injection (DI) และการจัดการข้อผิดพลาด โปรดดู /integrations/laravel/production-usage/
<?php
declare(strict_types=1);
use NextPDF\Contracts\PdfDocumentInterface;use NextPDF\Laravel\Http\PdfResponse;
$document = app(PdfDocumentInterface::class);$document->addPage();$document->cell(0, 10, 'Invoice', newLine: true);
return PdfResponse::download($document, 'invoice.pdf');กรณีขอบและข้อควรระวัง
หัวข้อที่มีชื่อว่า “กรณีขอบและข้อควรระวัง”- provider ถูกเลื่อนการลงทะเบียนไว้ การรีโซลฟ์คีย์ container ที่ไม่เกี่ยวข้องจึงไม่เริ่มการทำงานของ NextPDF และ binding จะปรากฏก็ต่อเมื่อมีการร้องขอรายการใดรายการหนึ่งของ
provides()เท่านั้น SignerInterfaceและTsaClientจะรีโซลฟ์เป็นnullโดยการออกแบบ เมื่อยังไม่ได้กำหนดค่าการลงนามหรือ timestamp authority โค้ดต้องตรวจสอบค่า null ของผลลัพธ์ และอย่าสันนิษฐานว่ามีอินสแตนซ์อยู่- binding ของสัญญา e-invoice จะถูกลงทะเบียนเสมอ แต่จะรีโซลฟ์ไปยังคลาส concrete ของ Premium ซึ่งมีอยู่เฉพาะเมื่อติดตั้ง
nextpdf/premiumเท่านั้น การรีโซลฟ์รายการเหล่านี้โดยไม่มี Premium จะทำให้เกิดข้อผิดพลาด class-not-found และข้อผิดพลาดจะปรากฏเมื่อรีโซลฟ์ครั้งแรก ไม่ใช่ตอนเริ่มทำงาน - facade จะคืนค่าเอกสารใหม่ในแต่ละการรีโซลฟ์ ให้พิจารณาการเรียก static
Pdf::สองครั้งในคำขอเดียวกันที่คั่นด้วยPdf::clearResolvedInstances(): การเรียกทั้งสองจะทำงานบนเอกสารที่ต่างกัน
ประสิทธิภาพ
หัวข้อที่มีชื่อว่า “ประสิทธิภาพ”การลงทะเบียน provider ทำงานในเวลา O(1) provider จะ bind closure และไม่สร้างอ็อบเจกต์ขนาดใหญ่ ต้นทุนการสร้างจึงถูกเลื่อนไปยังการรีโซลฟ์ครั้งแรก การอุ่นเครื่อง font registry ทำงานในเวลา O(f) โดยที่ f คือจำนวนไฟล์ฟอนต์ที่โหลดไว้ล่วงหน้า และทำงานหนึ่งครั้งต่อหนึ่งโพรเซส worker วิธีนี้ช่วยเฉลี่ยความหน่วงของคำขอแรกใน worker ที่มีอายุยาวนาน งบประมาณหน่วยความจำต่อหน้าสำหรับภาพรวมนี้ถูกบันทึกไว้ในฟิลด์ front-matter performance_budget
หมายเหตุด้านความปลอดภัย
หัวข้อที่มีชื่อว่า “หมายเหตุด้านความปลอดภัย”PdfResponse ใช้ชุด header แบบ Open Worldwide Application Security Project (OWASP) ที่กำหนดไว้คงที่ ชุดนี้ประกอบด้วย X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Content-Security-Policy: default-src 'none', X-Robots-Tag และ Referrer-Policy: no-referrer GeneratePdfJob ตรวจสอบความถูกต้องของพาธเอาต์พุตที่ฝั่ง worker ซึ่งช่วยลดความเสี่ยงจาก payload ที่ถูกซีเรียลไลซ์และถูกดัดแปลง สำหรับ threat model ฉบับเต็มและการกำหนดค่าการดีพลอย โปรดดู /integrations/laravel/security-and-operations/
ความสอดคล้องตามมาตรฐาน
หัวข้อที่มีชื่อว่า “ความสอดคล้องตามมาตรฐาน”| ข้ออ้าง | แหล่งที่มา | ข้อกำหนด | รหัสอ้างอิง (reference_id) |
|---|---|---|---|
| การรีโซลฟ์ของ container / ความหมายของอายุการใช้งาน | PSR-11 Container | §1.1.2 | |
| การแมปคำนำหน้า autoload แบบ PSR-4 | PSR-4 Autoloader | §3 |
บริบทเชิงพาณิชย์
หัวข้อที่มีชื่อว่า “บริบทเชิงพาณิชย์”เมื่อติดตั้ง nextpdf/premium provider เดียวกันจะเปิดเผยความสามารถเพิ่มเติม: การลงนามดิจิทัล (PAdES B-B), การจัดเก็บถาวรแบบ PDF/A และ binding ของสัญญา e-invoice โดยเปิดเผยความสามารถเหล่านี้ผ่านคีย์ container เดียวกัน โค้ดที่ใช้แพ็กเกจ Core ตามที่อธิบายไว้ในที่นี้จึงไม่ต้องเปลี่ยนแปลงเพื่อนำความสามารถเหล่านี้มาใช้ สำหรับรายละเอียด โปรดดู
https://nextpdf.dev/get-license/?intent=laravel-signing
ดูเพิ่มเติม
หัวข้อที่มีชื่อว่า “ดูเพิ่มเติม”- /integrations/laravel/install/ — ขั้นตอนการติดตั้งและส่วนขยายเสริม
- /integrations/laravel/quickstart/ — ตัวอย่าง controller ที่รันได้
- /integrations/laravel/configuration/ — คีย์ config ทั้งหมด ตรวจสอบเทียบกับ
config/nextpdf.php - /integrations/laravel/production-usage/ — controller ที่ใช้ DI พร้อมการจัดการข้อผิดพลาดและการเข้าคิว
- /integrations/laravel/boot-and-discovery/ — การค้นพบอัตโนมัติและอายุการใช้งานของ binding
- /integrations/laravel/security-and-operations/ — threat model และการกำหนดค่าการดีพลอย