Khởi động và tự động phát hiện NextPDF trong Laravel
Tổng quan nhanh
Phần tiêu đề “Tổng quan nhanh”Laravel tự động phát hiện NextPdfServiceProvider từ tệp composer.json của gói. Provider đăng ký các container binding dạng hoãn lại và xuất bản tệp cấu hình trong ngữ cảnh console. Trang này giải thích cơ chế phát hiện đó hoạt động ra sao và vòng đời của từng binding.
Cài đặt
Phần tiêu đề “Cài đặt”composer require nextpdf/laravelphp artisan vendor:publish --tag=nextpdf-configCách hoạt động của tính năng tự động phát hiện của Laravel
Phần tiêu đề “Cách hoạt động của tính năng tự động phát hiện của Laravel”Gói khai báo provider và facade alias trong khối extra.laravel của chính tệp composer.json:
{ "extra": { "laravel": { "providers": [ "NextPDF\\Laravel\\NextPdfServiceProvider" ], "aliases": { "Pdf": "NextPDF\\Laravel\\Facades\\Pdf" } } }}Khi bạn chạy composer require, Laravel đọc khối này rồi đăng ký provider và alias. Bạn không cần chỉnh sửa thủ công config/app.php hoặc bootstrap/providers.php. Mảng extra.laravel.providers tự động đăng ký các service provider, còn extra.laravel.aliases tự động đăng ký các facade alias (hướng dẫn phát triển gói Laravel 12,
https://laravel.com/docs/12.x/packages, truy cập ngày 2026-05-18).
Trình tự khởi động
Phần tiêu đề “Trình tự khởi động”NextPdfServiceProvider triển khai DeferrableProvider và vòng đời tiêu chuẩn register() / boot().
register()gộp cấu hình của gói vào khóanextpdf. Sau đó, phương thức này đăng ký binding cho các mục container: font registry, image registry, document factory, PHP Standards Recommendation 18 (PSR-18) Hypertext Transfer Protocol (HTTP) client, timestamp client, signer, document, và các e-invoice contract. Mỗi binding là một closure, nên không có thành phần nặng nào được khởi tạo tại đây.boot()kiểm tra xem các PHP extensionmbstringvàzlibđã được nạp hay chưa. Phương thức này chỉ đăng ký cấu hình có thể xuất bản dưới thẻnextpdf-configkhirunningInConsole()là true.
Vì provider được hoãn lại, register() chỉ chạy khi bạn resolve một trong các mục mà provides() trả về. Việc resolve một khóa container không liên quan sẽ không khởi động NextPDF.
Container binding và vòng đời
Phần tiêu đề “Container binding và vòng đời”PHP Standards Recommendation 11 (PSR-11) cho phép hai lệnh gọi get() liên tiếp với cùng một định danh trả về các giá trị khác nhau tùy theo chiến lược binding (PSR-11 §1.1.2). Provider chủ động dựa trên hành vi này:
| Khóa binding | Vòng đời | Ghi chú |
|---|---|---|
FontRegistryInterface (+ alias FontRegistry) | singleton, khóa sau khi khởi động nóng | Được khởi động nóng từ preload_fonts; đã khóa nên không request nào có thể thay đổi nó |
ImageRegistry | singleton | Bộ nhớ đệm least recently used (LRU) có giới hạn, kích thước theo image_cache_mb; không bị khóa |
DocumentFactoryInterface (+ alias DocumentFactory) | singleton | Không trạng thái; dùng chung hai registry |
Psr\Http\Client\ClientInterface | singleton | Client có cơ chế nhận biết tấn công giả mạo request, bao bọc một curl client; được tạo từ tsa.* |
TsaClient | scoped | null khi tsa.url rỗng |
SignerInterface | factory | null khi tắt ký hoặc chứng chỉ rỗng |
PdfDocumentInterface (+ alias nextpdf) | factory | Tạo mới NextPDF\Core\Document cho mỗi lần resolve, đã áp dụng metadata mặc định |
EmbedderInterface, ValidatorInterface, ProfileInterface, SchematronRunnerInterface | factory | Resolve thành các lớp cụ thể của Premium; báo lỗi ở lần resolve đầu tiên nếu thiếu nextpdf/premium |
Binding của document áp dụng defaults.creator, defaults.language, và, khi không rỗng, defaults.author cho mỗi tài liệu mới. Khi pdfa khác null, binding này bật PDF/A (Premium). Khi có phần artisan và lớp browser-factory của Chrome tồn tại, nó áp dụng cấu hình bộ kết xuất Chrome.
has() trên container nhận một định danh chuỗi duy nhất (PSR-11 §1.1.2). Các e-invoice contract đã có binding, nên has() trả về true cho chúng ngay cả khi không có Premium. Lớp cụ thể bị thiếu chỉ gây lỗi tại thời điểm khởi tạo.
Tắt tính năng tự động phát hiện
Phần tiêu đề “Tắt tính năng tự động phát hiện”Thêm gói vào mảng dont-discover của ứng dụng, rồi đăng ký provider theo cách thủ công:
{ "extra": { "laravel": { "dont-discover": ["nextpdf/laravel"] } }}<?php
declare(strict_types=1);
return [ App\Providers\AppServiceProvider::class, NextPDF\Laravel\NextPdfServiceProvider::class,];Thứ tự phân giải cấu hình
Phần tiêu đề “Thứ tự phân giải cấu hình”Mỗi khóa được phân giải theo thứ tự này: biến môi trường → giá trị config/nextpdf.php đã xuất bản → giá trị mặc định của gói đã được gộp tại register(). Hầu hết các khóa chấp nhận một tên NEXTPDF_* hoặc tên biến môi trường cũ TCPDF_*. Nên ưu tiên NEXTPDF_*.
Chẩn đoán
Phần tiêu đề “Chẩn đoán”php artisan package:discover --ansiMột dòng liệt kê nextpdf/laravel xác nhận việc phát hiện. Vì provider được hoãn lại, các binding chỉ xuất hiện sau lần resolve đầu tiên. Dòng phát hiện đó là tín hiệu thành công phù hợp.
Trường hợp đặc biệt và điểm cần lưu ý
Phần tiêu đề “Trường hợp đặc biệt và điểm cần lưu ý”- Việc xuất bản cấu hình chỉ được đăng ký trong ngữ cảnh console, nên một request web đơn thuần sẽ không bao giờ kích hoạt nó. Chạy
vendor:publishtừ giao diện dòng lệnh (CLI). - Bên cạnh các khóa registry, factory, HTTP client, signer, timestamp, và document,
provides()còn bao gồm bốn khóa e-invoice contract. - Một bản cài mới có thể trông như chưa hoạt động cho đến lần resolve liên quan đầu tiên. Đây là thiết kế provider hoãn lại, không phải lỗi.
Hiệu năng
Phần tiêu đề “Hiệu năng”register() là O(1) vì nó chỉ tạo các closure. Quá trình khởi động nóng font registry là O(f) theo số phông chữ được nạp trước và chạy một lần cho mỗi worker process. Việc hoãn lại provider giữ chi phí khởi tạo NextPDF nằm ngoài đường khởi động của framework cho đến khi một binding thực sự được dùng.
Ghi chú bảo mật
Phần tiêu đề “Ghi chú bảo mật”Thiết kế hoãn lại thu hẹp bề mặt tấn công tại thời điểm khởi động. Font registry bị khóa để ngăn một request thay đổi trạng thái phông chữ của request khác trong các worker tồn tại lâu dài. Để bao quát đầy đủ các mối đe dọa, xem /integrations/laravel/security-and-operations/.
Tuân thủ
Phần tiêu đề “Tuân thủ”| Tuyên bố | Nguồn | Điều khoản | reference_id |
|---|---|---|---|
| Các lần phân giải liên tiếp có thể khác nhau tùy theo chiến lược binding | PSR-11 Container | §1.1.2 | |
has() nhận một định danh chuỗi | PSR-11 Container | §1.1.2 |
Tài liệu chính thức về gói của Laravel 12 xác nhận tên các khóa phát hiện của Laravel (https://laravel.com/docs/12.x/packages, truy cập ngày 2026-05-18).
Bối cảnh thương mại
Phần tiêu đề “Bối cảnh thương mại”Các lớp cụ thể của Premium được phân giải qua cùng các khóa binding hoãn lại đó. Tính năng Enterprise tùy chọn này không cần thay đổi mã trong gói Core được mô tả ở đây. Xem https://nextpdf.dev/get-license/?intent=laravel-signing.
Xem thêm
Phần tiêu đề “Xem thêm”- /integrations/laravel/install/ — cài đặt và xuất bản
- /integrations/laravel/overview/ — kiến trúc gói
- /integrations/laravel/integration/ — hướng dẫn tích hợp từ đầu đến cuối
- /integrations/laravel/configuration/ — mọi khóa cấu hình