Hướng dẫn dành cho nhà phát triển Laravel
Tổng quan nhanh
Phần tiêu đề “Tổng quan nhanh”Gói Laravel đưa NextPDF vào đúng các quy ước của Laravel mà không thay đổi vòng đời tài liệu cốt lõi. Container sở hữu các registry và factory dùng chung. Mỗi tài liệu PDF chỉ dùng một lần, vì vậy bạn nên dựng, trả về, truyền luồng hoặc lưu tài liệu đúng một lần.
Hãy dùng hướng dẫn này khi thiết kế các service ứng dụng, queue job, luồng phản hồi hoặc phạm vi kiểm thử cho nextpdf/laravel.
Ranh giới kiến trúc
Phần tiêu đề “Ranh giới kiến trúc”| Tầng | Sở hữu bởi | Trách nhiệm | Không đặt ở đây |
|---|---|---|---|
| Controller | Ứng dụng | Xác thực quyền của yêu cầu, chọn một document builder và trả về phản hồi. | Các quy tắc bố cục PDF dùng chung cho nhiều trường hợp sử dụng. |
| Service ứng dụng | Ứng dụng | Thu thập dữ liệu nghiệp vụ và gọi mã dựng tài liệu. | Logic khởi động container hoặc cấu hình gói. |
| Document builder | Ứng dụng | Chuyển dữ liệu nghiệp vụ thành các lệnh gọi tài liệu của NextPDF. | Đối tượng request, logic truy vấn Eloquent hoặc chi tiết transport của queue. |
| Tích hợp Laravel | nextpdf/laravel | Liên kết các factory, registry, signer, client TSA, facade, response và queue job. | Đường dẫn lưu trữ riêng theo nghiệp vụ hoặc chính sách tenant. |
| Engine cốt lõi | nextpdf/nextpdf | Dựng và tuần tự hóa PDF. | Chính sách response, queue hoặc hệ thống tệp của Laravel. |
Vòng đời lúc chạy
Phần tiêu đề “Vòng đời lúc chạy”| Giai đoạn | Hành vi | Hành động của nhà phát triển |
|---|---|---|
| Đăng ký service provider | NextPdfServiceProvider::register() đăng ký các registry dùng chung, document factory, document binding, HTTP client, client của nhà cung cấp dấu thời gian (TSA), signer và các contract e-invoice tùy chọn. | Xuất bản và rà soát config/nextpdf.php trước khi đưa vào sản xuất. |
| Phân giải tài liệu | Facade Pdf và binding PdfDocumentInterface phân giải một tài liệu mới thông qua DocumentFactoryInterface. | Phân giải một tài liệu đúng một lần cho mỗi request, command hoặc queued job. |
| Soạn thảo | Mã ứng dụng gọi các API tài liệu cốt lõi thông qua facade hoặc tài liệu được inject. | Giữ phần trích xuất dữ liệu nghiệp vụ bên ngoài document builder. |
| Đầu ra cuối | PdfResponse xuất đầu ra HTTP, hoặc tài liệu được lưu vào đĩa. | Chọn một đường dẫn đầu ra cuối cho mỗi tài liệu. |
| Thực thi trên queue | GeneratePdfJob dựng lại tài liệu trong worker và xác thực lại đường dẫn đầu ra. | Truyền ngữ cảnh dạng vô hướng và giữ các callback có tính idempotent. |
Cấu trúc ứng dụng được khuyến nghị
Phần tiêu đề “Cấu trúc ứng dụng được khuyến nghị”| Đường dẫn | Mục đích |
|---|---|
app/Pdf/Builders/* | Các document builder thuần túy. Chúng nhận dữ liệu và trả về một tài liệu hoàn chỉnh. |
app/Pdf/Data/* | Các đối tượng truyền dữ liệu (DTO) nhỏ, mang dữ liệu đầu vào tài liệu đã được xác thực quyền. |
app/Services/* | Điều phối ứng dụng, truy vấn, chuyển tiếp kết quả xác thực quyền và chọn đường dẫn lưu trữ. |
app/Jobs/* | Các lớp bao tùy chọn quanh GeneratePdfJob khi ứng dụng cần các job có tên riêng. |
tests/Feature/Pdf/* | Các bài kiểm thử phản hồi HTTP, điều phối queue và xác thực quyền. |
tests/Unit/Pdf/* | Các bài kiểm thử builder với dữ liệu đầu vào nhỏ và tất định. |
Giữ các builder độc lập với đối tượng request của Laravel. Bạn cần có thể gọi cùng một builder từ controller, command, bài kiểm thử hoặc queue worker với cùng một đầu vào.
<?php
namespace App\Pdf\Builders;
use App\Pdf\Data\InvoicePdfData;use NextPDF\Contracts\PdfDocumentInterface;
final readonly class InvoicePdfBuilder{ public function build(PdfDocumentInterface $pdf, InvoicePdfData $data): PdfDocumentInterface { $pdf->setTitle($data->title) ->addPage() ->setFont('dejavusans', '', 12) ->writeHtml($data->html);
return $pdf; }}Mẫu phản hồi đồng bộ
Phần tiêu đề “Mẫu phản hồi đồng bộ”Dùng constructor injection khi luồng PDF là một phần của logic ứng dụng. Chỉ dùng facade cho các luồng controller ngắn, nơi cách viết tĩnh dễ đọc hơn.
<?php
namespace App\Http\Controllers;
use App\Pdf\Builders\InvoicePdfBuilder;use App\Pdf\Data\InvoicePdfData;use NextPDF\Contracts\PdfDocumentInterface;use NextPDF\Laravel\Http\PdfResponse;
final readonly class DownloadInvoiceController{ public function __invoke( PdfDocumentInterface $pdf, InvoicePdfBuilder $builder, ) { $document = $builder->build( $pdf, InvoicePdfData::fromInvoiceId(1234), );
return PdfResponse::download($document, 'invoice-1234.pdf'); }}Các response helper hiện thực hóa byte tài liệu trước khi dựng phản hồi Laravel. Chúng là response helper, không phải trình kết xuất chạy nền.
Mẫu queue
Phần tiêu đề “Mẫu queue”GeneratePdfJob nhận một builder callable và một đường dẫn đầu ra. Job xác thực các đường dẫn không an toàn tại thời điểm thực thi. Mã ứng dụng vẫn nên chọn thư mục gốc lưu trữ an toàn theo tenant trước khi điều phối.
<?php
use App\Pdf\Builders\QueuedInvoiceBuilder;use NextPDF\Laravel\Jobs\GeneratePdfJob;
GeneratePdfJob::dispatch( outputPath: storage_path('app/pdfs/invoice-1234.pdf'), builder: [QueuedInvoiceBuilder::class, 'build'],)->onQueue(config('nextpdf.queue.queue', 'pdf'));Giữ các callback của queue thật gọn. Hãy ưu tiên ghi trạng thái bền vững từ một application job listener thay vì lưu các closure phức tạp trong payload của queue.
Điểm mở rộng
Phần tiêu đề “Điểm mở rộng”| Điểm mở rộng | Dùng cho | Ràng buộc |
|---|---|---|
PdfDocumentInterface binding | Thay thế hoặc trang trí việc tạo tài liệu cho các giá trị mặc định trên toàn ứng dụng. | Phải trả về một thực thể tài liệu mới. |
DocumentFactoryInterface | Tạo các tài liệu mới một cách tường minh trong các service và bài kiểm thử. | Không cache các tài liệu được trả về. |
config/nextpdf.php | Các giá trị mặc định, thiết lập queue, thiết lập trình kết xuất Chrome, hook ký, cache TSA, OCSP. | Hãy xem biến môi trường là cấu hình triển khai, không phải đầu vào của request. |
GeneratePdfJob builder | Dựng tài liệu một cách bất đồng bộ. | Callable phải có thể được tuần tự hóa bởi transport queue của Laravel. |
| Callback thành công/thất bại | Thông báo hoặc dọn dẹp sau khi tạo. | Giữ các callback có tính idempotent và lưu ý đến tác dụng phụ. |
| Các contract Premium tùy chọn | Trình nhúng e-invoice, trình xác thực, profile và trình chạy Schematron. | Chỉ phân giải ở nơi gói tùy chọn đã được cài đặt và có giấy phép. |
Quy trình phát triển
Phần tiêu đề “Quy trình phát triển”- Dựng tài liệu đầu tiên theo cách đồng bộ trong một controller hoặc một bài kiểm thử tính năng.
- Chuyển mã bố cục vào một lớp builder trong
app/Pdf/Builders. - Chuyển logic truy vấn và xác thực quyền vào một service ứng dụng.
- Thêm các bài kiểm thử
PdfResponsecho header và tên tệp. - Chuyển việc tạo tài liệu chậm hoặc có khối lượng lớn sang
GeneratePdfJob. - Thêm các bài kiểm thử queue cho ngữ cảnh được tuần tự hóa, chính sách đường dẫn đầu ra và xử lý lỗi.
- Đo bộ nhớ và thời gian kết xuất với dữ liệu sản xuất tiêu biểu.
Xử lý lỗi
Phần tiêu đề “Xử lý lỗi”| Lỗi | Nơi cần xử lý | Phản hồi được khuyến nghị |
|---|---|---|
| Yêu cầu không hợp lệ hoặc tài liệu chưa được cấp quyền | Controller hoặc policy. | Trả về phản hồi xác thực quyền hoặc kiểm tra hợp lệ thông thường của ứng dụng. |
| Thiếu phông chữ hoặc hình ảnh không hợp lệ | Bài kiểm thử builder và ghi log ứng dụng. | Để yêu cầu hoặc job thất bại; không phát ra PDF không hoàn chỉnh. |
| Đường dẫn đầu ra không an toàn | Service lưu trữ của ứng dụng và GeneratePdfJob. | Từ chối trước khi điều phối và dựa vào xác thực ở phía worker như một lớp phòng thủ chiều sâu. |
| Lỗi ký hoặc TSA | Ranh giới của service ký. | Quyết định xem tài liệu có thể không được ký hay không; mặc định là fail closed đối với các tài liệu chịu quản lý pháp lý. |
| Hết thời gian chờ queue | Cấu hình queue worker và khả năng quan sát. | Chỉ thử lại khi builder có tính tất định và đường dẫn đầu ra an toàn để ghi đè. |
Giá trị mặc định an toàn
Phần tiêu đề “Giá trị mặc định an toàn”| Mối quan tâm | Mặc định | Khi nào nên ghi đè |
|---|---|---|
| Tên queue | pdf | Dùng một queue riêng khi việc tạo tài liệu cạnh tranh với các job phục vụ người dùng. |
| Thời gian chờ của job | 120 giây | Chỉ tăng sau khi đã đo kích thước tài liệu và năng lực của worker. |
| Tên tệp phản hồi | document.pdf | Dùng các định danh nghiệp vụ đã được làm sạch. |
| Registry phông chữ | Dùng chung và bị khóa sau khi khởi động làm nóng. | Thêm preload_fonts cho các phông chữ được dùng trên các đường dẫn nóng. |
| Registry hình ảnh | Cache có giới hạn dùng chung. | Giảm image_cache_mb cho các worker bị hạn chế bộ nhớ. |
| Chia khối phản hồi truyền luồng | Các khối 64 KB. | Không phụ thuộc vào ranh giới khối; chúng là một chi tiết của đầu ra. |
Danh sách kiểm thử
Phần tiêu đề “Danh sách kiểm thử”- Các bài kiểm thử controller khẳng định
Content-Type,Content-Dispositionvà các header phòng thủ. - Các bài kiểm thử builder dùng các DTO mang tính tất định và không truy vấn cơ sở dữ liệu.
- Các bài kiểm thử queue khẳng định builder nhận được một tài liệu mới.
- Các bài kiểm thử đường dẫn bao quát việc duyệt thư mục, stream-wrapper, null-byte và việc từ chối tệp không phải
.pdf. - Các bài kiểm thử worker kết xuất các tài liệu tiêu biểu với cùng giới hạn bộ nhớ như trong sản xuất.
- Các bài kiểm thử ký tùy chọn bao quát chứng chỉ bị thiếu, mật khẩu không hợp lệ, TSA không khả dụng và mức chữ ký đã cấu hình.