Bỏ qua để đến nội dung

Khởi động và phát hiện NextPDF Artisan

Artisan là một thư viện thuần túy tuân thủ PHP Standard Recommendation 4 (PSR-4). Nó không có service provider, bundle hay manifest tự động phát hiện của framework. Nó khởi động ngay khi các class của nó có thể được autoload. Cơ chế phát hiện chỉ là bản đồ PSR-4 của Composer, không hơn.

Tệp composer.json của gói khai báo hai gốc PSR-4: NextPDF\Artisan\src/Artisan/NextPDF\Parser\src/Parser/. Nó không bao gồm extra.laravel, class bundle của Symfony hay registrar của CodeIgniter. Không có thành phần nào quét, đăng ký hay móc nối trong lúc khởi động.

Điểm tích hợp nằm trong nextpdf/core. Document (thông qua concern HasTextOutput) cung cấp writeHtmlChrome(), hàm này kiểm tra class_exists() tại thời điểm chạy đối với NextPDF\Parser\PdfReaderNextPDF\Artisan\PageImporter. Khi autoloader phân giải được cả hai class, đường dẫn Chrome sẽ sẵn sàng. Khi không phân giải được, core đưa ra một layout exception thay vì dừng bằng lỗi nghiêm trọng. Vì vậy, việc phát hiện chỉ đặt một câu hỏi: các class Artisan có nằm trong autoloader không? Composer trả lời câu hỏi đó; không có cơ chế nào của framework tham gia.

Đây là chủ đích. Cầu nối này là một khả năng mà engine lõi gọi tới qua ranh giới của gói, không phải một dịch vụ do framework quản lý. Bạn có thể dùng Artisan theo cùng một cách trong Laravel, Symfony, CodeIgniter, một script dòng lệnh (CLI) hay một queue worker, vì không host nào trong số đó là bắt buộc.

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 không có bootstrap kernel, đăng ký lệnh hay giai đoạn deferred-provider. Chính lệnh gọi writeHtmlChrome() đầu tiên là toàn bộ điểm vào của vòng đời.

Artisan không dùng container dependency injection (DI) và không đăng ký liên kết nào. Các thành phần của nó là những đối tượng thuần túy được tiêm qua constructor: tạo một ChromeRendererConfig, truyền nó vào ChromeHtmlRenderer, rồi tùy chọn tiêm một logger PSR-3 cùng một HtmlSecurityPolicyInterface tùy chỉnh. Trong container của host, hãy tự đăng ký ChromeHtmlRenderer dưới dạng singleton; xem ví dụ tại /integrations/artisan/production-usage/.

Một số khả năng của NextPDF, bao gồm các contract hóa đơn điện tử Premium, thường được phân giải thông qua container của framework. Artisan cũng chạy trong các môi trường không dùng container, chẳng hạn như công cụ CLI, script độc lập và custom runner, vì vậy nó đi kèm EInvoiceServiceFactory:

Phương thứcTrả vềKhi null
makeEmbedder()EmbedderInterface (Pro)Chưa cài đặt bậc Pro
makeValidator()ValidatorInterface (Enterprise)Chưa cài đặt bậc Enterprise
makeDefaultProfile()ProfileInterface (EN16931, Pro)Chưa cài đặt bậc Pro
makeSchematronRunner()SchematronRunnerInterface (Enterprise)Chưa cài đặt bậc Enterprise

Mỗi lệnh gọi trả về một instance mới. Hành vi dùng một lần này quan trọng vì các lệnh gọi embed và validate giữ một ngữ cảnh phân tích Extensible Markup Language (XML) có thể thay đổi và không được chia sẻ trạng thái. Factory này là tiện ích cho trường hợp hiếm khi không có container, không phải một service locator. Mẫu hình được ưu tiên vẫn là kết hợp các đối tượng khi khởi tạo và truyền chúng làm đối số của constructor. Việc trả về null khi thiếu một bậc phản ánh đúng các gói wrapper của framework, nhờ vậy cùng một đoạn mã gọi vẫn chạy được dù có hay không có Premium. Nguồn: src/Artisan/EInvoiceServiceFactory.php; được kiểm thử tích hợp trong tests/Integration/Artisan/EInvoiceServiceFactoryIntegrationTest.php.

Không có chuỗi xếp tầng các tệp cấu hình. Cấu hình thực tế chính là những gì bạn truyền vào ChromeRendererConfig:

  1. Các đối số của constructor mà bạn truyền vào một cách tường minh, hoặc
  2. ChromeRendererConfig::fromArray() từ một mảng do host cung cấp (khóa kiểu snake-case; các khóa không được đặt sẽ quay về giá trị mặc định của constructor; chrome_binary chỉ áp dụng khi nó là chuỗi không rỗng).

Cấu hình đã phân giải là bất biến trong suốt vòng đời của renderer. Xem /integrations/artisan/configuration/ để biết toàn bộ khóa.

  • “Cầu nối có thể phát hiện được không?” — nếu class_exists(\NextPDF\Artisan\PageImporter::class)true, autoloader của Composer có thể tìm thấy class này và core sẽ dùng đường dẫn Chrome.
  • “Nó đã khởi động chưa?” — không có giai đoạn khởi động riêng nào có thể thất bại; một dependency bị thiếu sẽ lộ ra ở lệnh gọi writeHtmlChrome() đầu tiên dưới dạng một exception có kiểu, được ánh xạ tại /integrations/artisan/troubleshooting/.
  • Kiểm tra Premium không dùng containerEInvoiceServiceFactory::makeEmbedder() === null nghĩa là bậc Pro chưa được cài đặt; đường dẫn kết xuất mã nguồn mở không bị ảnh hưởng.
  • /integrations/artisan/integration/
  • /integrations/artisan/overview/
  • /integrations/artisan/configuration/
  • /integrations/artisan/production-usage/
  • /integrations/artisan/troubleshooting/