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

การบูตและการดิสคัฟเวอรีของ NextPDF Artisan

Artisan เป็นไลบรารีขนาดเล็กที่ปฏิบัติตาม PHP Standard Recommendation 4 (PSR-4) ไม่มี service provider, bundle หรือ manifest สำหรับการดิสคัฟเวอรีอัตโนมัติของเฟรมเวิร์ก ไลบรารีจะบูตทันทีเมื่อคลาสต่าง ๆ ถูกออโตโหลดได้ การดิสคัฟเวอรีมีเพียง PSR-4 map ของ Composer เท่านั้น ไม่มีอย่างอื่นเพิ่มเติม

composer.json ของแพ็กเกจประกาศ PSR-4 root สองรายการ: NextPDF\Artisan\src/Artisan/ และ NextPDF\Parser\src/Parser/ แพ็กเกจนี้ไม่มี extra.laravel คลาส bundle ของ Symfony หรือ registrar ของ CodeIgniter จึงไม่มีสิ่งใดสแกน ลงทะเบียน หรือ hook ระหว่างการบูต

จุดอินทิเกรชันอยู่ใน nextpdf/core: Document (ผ่าน concern HasTextOutput) เปิดให้ใช้ writeHtmlChrome() ซึ่งตรวจสอบ class_exists() ที่รันไทม์สำหรับ NextPDF\Parser\PdfReader และ NextPDF\Artisan\PageImporter เมื่อออโตโหลดเดอร์รีโซลฟ์คลาสทั้งสองได้ เส้นทาง Chrome ก็พร้อมใช้งาน หากรีโซลฟ์ไม่ได้ core จะยก layout exception แทนการล้มเหลวด้วย fatal error ดังนั้นการดิสคัฟเวอรีจึงมีคำถามเดียว: คลาสของ Artisan อยู่ในออโตโหลดเดอร์หรือไม่? Composer เป็นผู้ตอบคำถามนี้ โดยไม่มีกลไกของเฟรมเวิร์กเข้ามาเกี่ยวข้อง

นี่เป็นการออกแบบโดยเจตนา บริดจ์เป็นความสามารถที่เอนจิน core เข้าถึงข้ามขอบเขตแพ็กเกจ ไม่ใช่เซอร์วิสที่เฟรมเวิร์กจัดการ คุณจึงใช้ Artisan ด้วยรูปแบบเดียวกันได้ใน Laravel, Symfony, CodeIgniter, สคริปต์ command-line interface (CLI) หรือ queue worker เพราะไม่ต้องพึ่งโฮสต์เหล่านั้น

no

yes

Composer autoload (PSR-4)

Application constructs Document

Document::setChromeRendererConfig(config)

Document::writeHtmlChrome(html)

class_exists PdfReader

and PageImporter?

core raises layout exception

resolve ChromeHtmlRenderer

render → parse → import Form XObject

Diagram

Artisan ไม่มี bootstrap kernel ไม่มีการลงทะเบียนคำสั่ง และไม่มีเฟส deferred-provider การเรียก writeHtmlChrome() ครั้งแรกคือจุดเข้าสู่ไลฟ์ไซเคิลทั้งหมด

Artisan ไม่มีคอนเทนเนอร์ dependency injection (DI) และไม่ลงทะเบียน binding ใด ๆ คอมโพเนนต์ต่าง ๆ เป็นออบเจ็กต์ธรรมดาที่ฉีดผ่าน constructor: สร้าง ChromeRendererConfig ส่งต่อไปยัง ChromeHtmlRenderer และจะฉีด PSR-3 logger รวมถึง HtmlSecurityPolicyInterface แบบกำหนดเองได้ตามต้องการ ในคอนเทนเนอร์ของโฮสต์ ให้ลงทะเบียน ChromeHtmlRenderer เป็น singleton ด้วยตนเอง ดูตัวอย่างได้ที่ /integrations/artisan/production-usage/

ความสามารถบางอย่างของ NextPDF รวมถึง Premium e-invoice contracts มักรีโซลฟ์ผ่านคอนเทนเนอร์ของเฟรมเวิร์ก แต่ Artisan ยังทำงานได้ในสภาพแวดล้อมที่ไม่มีคอนเทนเนอร์ เช่น เครื่องมือ CLI สคริปต์แบบ standalone และ runner แบบกำหนดเอง จึงมาพร้อมกับ EInvoiceServiceFactory:

เมท็อดคืนค่าเมื่อคืนค่าเป็น null
makeEmbedder()EmbedderInterface (Pro)ไม่ได้ติดตั้งรุ่น Pro
makeValidator()ValidatorInterface (Enterprise)ไม่ได้ติดตั้งรุ่น Enterprise
makeDefaultProfile()ProfileInterface (EN16931, Pro)ไม่ได้ติดตั้งรุ่น Pro
makeSchematronRunner()SchematronRunnerInterface (Enterprise)ไม่ได้ติดตั้งรุ่น Enterprise

การเรียกแต่ละครั้งจะคืนค่าอินสแตนซ์ ใหม่ พฤติกรรมแบบใช้ครั้งเดียวนี้มีความสำคัญ เพราะการเรียก embed และ validate เป็นเจ้าของ parse context ของ Extensible Markup Language (XML) ที่เปลี่ยนแปลงได้ และต้องไม่ใช้สถานะร่วมกัน factory นี้เป็นตัวช่วยสำหรับกรณีไม่มีคอนเทนเนอร์ที่พบไม่บ่อย ไม่ใช่ service locator รูปแบบที่แนะนำยังคงเป็นการประกอบออบเจ็กต์ในขั้นตอนการสร้าง แล้วส่งต่อเป็นอาร์กิวเมนต์ของ constructor การคืนค่า null เมื่อไม่มีรุ่นนั้นสะท้อนพฤติกรรมเดียวกับแพ็กเกจ wrapper ของเฟรมเวิร์ก ดังนั้นโค้ดชุดเดียวกันจึงทำงานได้ทั้งเมื่อมีและไม่มี Premium ซอร์สอยู่ที่: src/Artisan/EInvoiceServiceFactory.php และมีการทดสอบอินทิเกรชันใน tests/Integration/Artisan/EInvoiceServiceFactoryIntegrationTest.php

ไม่มีการ cascade ไฟล์การกำหนดค่า การกำหนดค่าคือค่าที่คุณส่งให้ ChromeRendererConfig โดยตรง:

  1. อาร์กิวเมนต์ของ constructor ที่คุณส่งเข้าไปอย่างชัดเจน หรือ
  2. ChromeRendererConfig::fromArray() จากอาร์เรย์ที่โฮสต์จัดเตรียมให้ (คีย์ใช้รูปแบบ snake-case คีย์ที่ไม่ได้กำหนดจะใช้ค่าเริ่มต้นของ constructor แทน chrome_binary จะมีผลเฉพาะเมื่อเป็นสตริงที่ไม่ว่างเปล่า)

หลังจากรีโซลฟ์แล้ว การกำหนดค่าจะเปลี่ยนแปลงไม่ได้ตลอดอายุการใช้งานของเรนเดอเรอร์ ดูคีย์ทั้งหมดได้ที่ /integrations/artisan/configuration/

  • “บริดจ์ดิสคัฟเวอร์ได้หรือไม่?” — หาก class_exists(\NextPDF\Artisan\PageImporter::class) เป็น true แสดงว่าออโตโหลดเดอร์ของ Composer ค้นพบได้ และ core จะใช้เส้นทาง Chrome
  • “บูตสำเร็จหรือไม่?” — ไม่มีเฟสการบูตที่อาจล้มเหลว ดีเพนเดนซีที่ขาดหายจะปรากฏเมื่อเรียก writeHtmlChrome() ครั้งแรกในรูปแบบ exception ที่มีชนิด ตามที่แมปไว้ที่ /integrations/artisan/troubleshooting/
  • การตรวจสอบ Premium แบบไม่มีคอนเทนเนอร์EInvoiceServiceFactory::makeEmbedder() === null หมายความว่าไม่ได้ติดตั้งรุ่น Pro ส่วนเส้นทางการเรนเดอร์แบบโอเพนซอร์สจะไม่ได้รับผลกระทบ
  • การผสานรวม (/integrations/artisan/integration/)
  • ภาพรวม (/integrations/artisan/overview/)
  • การกำหนดค่า (/integrations/artisan/configuration/)
  • การใช้งานจริง (/integrations/artisan/production-usage/)
  • การแก้ปัญหา (/integrations/artisan/troubleshooting/)