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

ภาพรวมการผสานการทำงาน NextPDF Laravel

แพ็กเกจ nextpdf/laravel เชื่อมต่อเอนจิน PDF ของ NextPDF เข้ากับแอปพลิเคชัน Laravel 12 และลงทะเบียน container binding ให้โดยอัตโนมัติ แพ็กเกจนี้มี facade Pdf ตัวช่วย HTTP PdfResponse และงานคิว GeneratePdfJob ระบบ package discovery ของ Laravel จะตรวจพบแพ็กเกจนี้โดยอัตโนมัติ จึงไม่จำเป็นต้องลงทะเบียนด้วยตนเอง

Terminal window
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 ของแกนหลักที่ใช้ร่วมกัน

NextPDF Laravel request and render flowA request resolves a fresh document from the container, which the package adapts onto the shared font and image registries before HTTP or queue output.

Your Laravel app

Pdf facade

Laravel service container

NextPdfServiceProvider (deferred)

DocumentFactory (singleton)

Document (fresh per resolve)

FontRegistry (singleton, locked)

ImageRegistry (singleton, LRU)

PdfResponse (HTTP)

GeneratePdfJob (queue worker)

NextPDF Laravel request and render flow

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 ที่รีโซลฟ์เอกสารใหม่จาก container
  • NextPDF\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 เสมอ สถานะที่เปลี่ยนแปลงได้ต่อคำขอจึงไม่รั่วไหลข้ามคำขอ

คลาสจุดเข้าใช้งานสาธารณะค่าที่คืนวัตถุประสงค์
NextPdfServiceProviderregister(), boot(), provides()void / arraycontainer binding, การเผยแพร่ config, รายการบริการที่เลื่อนการลงทะเบียนไว้
Facades\Pdfstatic proxy (addPage(), cell(), save(), …)static / mixedรีโซลฟ์ PdfDocumentInterface ในแต่ละการเรียก
Http\PdfResponseinline(), download(), streamInline(), streamDownload()Response / StreamedResponseHTTP response พร้อม header แบบ Open Worldwide Application Security Project (OWASP)
Jobs\GeneratePdfJobdispatch(), handle(), then(), catch(), failed()PendingDispatch / void / selfการสร้าง PDF แบบเข้าคิว

คีย์ container ที่ provider bind ไว้:

คีย์อายุการใช้งานรีโซลฟ์ไปยัง
NextPDF\Contracts\FontRegistryInterface (alias FontRegistry)singleton, ล็อกไว้NextPDF\Typography\FontRegistry
NextPDF\Graphics\ImageRegistrysingleton, จำกัดด้วย LRUImageRegistry
NextPDF\Contracts\DocumentFactoryInterface (alias DocumentFactory)singletonNextPDF\Core\DocumentFactory
Psr\Http\Client\ClientInterfacesingletonSecurityAwareHttpClient ที่ห่อหุ้ม CurlHttpClient
NextPDF\Security\Timestamp\TsaClientscopedTsaClient หรือ null เมื่อไม่มี URL ของ timestamp authority (TSA)
NextPDF\Contracts\SignerInterfacefactoryDigitalSigner หรือ null เมื่อปิดใช้งานการลงนาม
NextPDF\Contracts\PdfDocumentInterface (alias nextpdf)factoryNextPDF\Core\Document
NextPDF\Contracts\EInvoice\{Embedder,Validator,Profile,SchematronRunner}Interfacefactoryรีโซลฟ์ได้เฉพาะเมื่อติดตั้ง nextpdf/premium เท่านั้น
resource: README.md Quick Start (verified against src/Laravel/Facades/Pdf.php)
<?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/

resource: src/Laravel/Http/PdfResponse.php (download factory)
<?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-4PSR-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 และการกำหนดค่าการดีพลอย