Bắt đầu nhanh với NextPDF Symfony
Tổng quan nhanh
Phần tiêu đề “Tổng quan nhanh”Inject PdfFactory, tạo một Document, rồi trả về qua PdfResponse. Khi cần tạo ở chế độ nền, hãy dispatch một GeneratePdfMessage đến một transport của Messenger.
Bước 1 — Tạo PDF trong một controller
Phần tiêu đề “Bước 1 — Tạo PDF trong một controller”Inject NextPDF\Symfony\Service\PdfFactory. Phương thức create() trả về một NextPDF\Core\Document mới và áp dụng các giá trị mặc định bạn đã cấu hình cho creator, author và ngôn ngữ. Trả tài liệu về qua NextPDF\Symfony\Http\PdfResponse.
<?php
declare(strict_types=1);
namespace App\Controller;
use NextPDF\Symfony\Http\PdfResponse;use NextPDF\Symfony\Service\PdfFactory;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\Routing\Attribute\Route;
final class InvoiceController{ #[Route('/invoice/{number}', name: 'invoice_pdf')] public function download(PdfFactory $pdf, string $number): Response { $doc = $pdf->create(); $doc->addPage(); $doc->cell(0, 10, "Invoice #{$number}", newLine: true); $doc->cell(0, 10, 'Thank you for your business.');
return PdfResponse::download($doc, "invoice-{$number}.pdf"); }}PdfResponse::download() trả về một Symfony\Component\HttpFoundation\Response. Phương thức này thiết lập Content-Type: application/pdf, disposition attachment, Content-Length, và các header bảo mật cố định của bundle. Symfony ghi tài liệu vào lớp Response chuẩn và mô hình header của lớp này (https://symfony.com/doc/current/components/http_foundation.html).
Bước 2 — Hiển thị PDF nội tuyến
Phần tiêu đề “Bước 2 — Hiển thị PDF nội tuyến”Dùng inline() khi bạn muốn trình duyệt hiển thị PDF thay vì tải xuống:
return PdfResponse::inline($doc, 'preview.pdf');Disposition được đổi thành inline. Tất cả các header khác giữ nguyên.
Bước 3 — Truyền luồng một PDF lớn
Phần tiêu đề “Bước 3 — Truyền luồng một PDF lớn”Dùng các biến thể truyền luồng cho tài liệu lớn. Các biến thể này phát PDF theo từng khối 64 KB, nhờ đó giảm mức sử dụng bộ nhớ đỉnh. Chúng trả về một Symfony\Component\HttpFoundation\StreamedResponse và bỏ qua Content-Length.
return PdfResponse::streamDownload($doc, 'annual-report.pdf');Dùng streamInline() để truyền luồng nội tuyến. Symfony ghi tài liệu theo hợp đồng callback của StreamedResponse, tức một callable void dùng để flush đầu ra (https://symfony.com/doc/current/components/http_foundation.html).
Bước 4 — Tạo PDF bất đồng bộ
Phần tiêu đề “Bước 4 — Tạo PDF bất đồng bộ”Khi đã cài đặt symfony/messenger, bạn có thể tách việc tạo PDF khỏi luồng xử lý request.
4a — Triển khai một builder
Phần tiêu đề “4a — Triển khai một builder”Triển khai NextPDF\Symfony\Message\PdfBuilderInterface. Handler cung cấp một Document mới đã được cấu hình sẵn cùng context có thể tuần tự hóa lấy từ message.
<?php
declare(strict_types=1);
namespace App\Pdf;
use NextPDF\Core\Document;use NextPDF\Symfony\Message\PdfBuilderInterface;
final class InvoicePdfBuilder implements PdfBuilderInterface{ public function build(Document $document, array $context): Document { $document->addPage(); $document->setFont('dejavusans', '', 12); $document->cell(0, 10, 'Invoice #' . $context['invoice_id']);
return $document; }}4b — Đăng ký builder trong locator
Phần tiêu đề “4b — Đăng ký builder trong locator”Handler phân giải các builder từ một service locator PHP Standard Recommendation 11 (PSR-11), được lập chỉ mục theo tên lớp. Chỉ những builder đã đăng ký mới truy cập được. Thêm builder vào một locator trong config/services.yaml:
services: App\Pdf\InvoicePdfBuilder: ~
nextpdf.pdf_builder_locator: class: Symfony\Component\DependencyInjection\ServiceLocator arguments: - 'App\Pdf\InvoicePdfBuilder': '@App\Pdf\InvoicePdfBuilder' tags: ['container.service_locator']
NextPDF\Symfony\Message\GeneratePdfHandler: arguments: $builderLocator: '@nextpdf.pdf_builder_locator'Handler yêu cầu locator cung cấp builder theo id dạng class-string của builder đó. Trong PSR-11, một định danh container là một chuỗi xác định duy nhất một entry (PSR-11 §1.1.2).
4c — Dispatch message
Phần tiêu đề “4c — Dispatch message”Inject Symfony\Component\Messenger\MessageBusInterface, rồi dispatch message:
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Pdf\InvoicePdfBuilder;use NextPDF\Symfony\Message\GeneratePdfMessage;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\Messenger\MessageBusInterface;use Symfony\Component\Routing\Attribute\Route;
final class ReportController{ #[Route('/invoice/{id}/queue', name: 'invoice_queue')] public function queue(MessageBusInterface $bus, int $id): Response { $bus->dispatch(new GeneratePdfMessage( builderClass: InvoicePdfBuilder::class, outputPath: '/var/storage/invoices/' . $id . '.pdf', builderContext: ['invoice_id' => $id], ));
return new Response('PDF generation queued.', 202); }}GeneratePdfMessage là một data transfer object (DTO) readonly. Constructor của nó từ chối đường dẫn đầu ra rỗng, không kết thúc bằng .pdf, chứa các đoạn path-traversal, dùng lược đồ stream-wrapper, hoặc chứa null byte. Nó cũng yêu cầu builderClass phải là tên lớp hợp lệ về mặt cú pháp. Handler xác thực lại đường dẫn đầu ra vào thời điểm thực thi, trước khi ghi. Nếu một đường dẫn an toàn lúc dispatch nhưng không an toàn lúc tiêu thụ, handler vẫn từ chối nó. Attribute #[AsMessageHandler] và hợp đồng dispatch của MessageBusInterface tuân theo mô hình Symfony Messenger chuẩn (https://symfony.com/doc/current/messenger.html).
4d — Định tuyến message và chạy một worker
Phần tiêu đề “4d — Định tuyến message và chạy một worker”Trong config/packages/messenger.yaml, hãy định tuyến message đến một transport:
framework: messenger: transports: async: '%env(MESSENGER_TRANSPORT_DSN)%' routing: NextPDF\Symfony\Message\GeneratePdfMessage: asyncSau đó chạy một worker:
php bin/console messenger:consume asyncXác minh hoạt động
Phần tiêu đề “Xác minh hoạt động”php bin/console debug:container --tag=container.service_locatorphp bin/console messenger:consume async --limit=1 -vvLệnh đầu tiên xác nhận builder locator đã được đăng ký. Lệnh thứ hai tiêu thụ một message trong hàng đợi và in tiến trình của handler.
Bước tiếp theo
Phần tiêu đề “Bước tiếp theo”- /integrations/symfony/configuration/ — điều chỉnh các giá trị mặc định, phông chữ và document service.
- /integrations/symfony/production-usage/ — xem lại an toàn của worker và việc truyền luồng dưới tải.
- /integrations/symfony/troubleshooting/ — xử lý các vấn đề khởi động và lúc chạy thường gặp.
Tuân thủ
Phần tiêu đề “Tuân thủ”Mỗi hàng là một tuyên bố chuẩn tắc được nêu trên trang này và được gắn với một reference_id 64-hex đầy đủ từ kho ngữ liệu của tổ chức phát triển tiêu chuẩn (SDO) có kiểm soát. _sidecars/rag-citations.yaml chứa nguồn gốc, bao gồm manifest của kho ngữ liệu và transport truy xuất.
| Đặc tả | Điều khoản | reference_id | Tuyên bố |
|---|---|---|---|
| PSR-11 | psr_11_container#1.1.2.p4 | Hợp đồng định danh has()/get() của container |
Xem thêm
Phần tiêu đề “Xem thêm”- /integrations/symfony/overview/ — xem lại bản tóm tắt năng lực.
- /integrations/symfony/install/ — cài đặt và đăng ký bundle.
- /integrations/symfony/integration/ — xem lại tài liệu tham chiếu về cách đấu nối đầu-cuối.