NextPDF Symfony クイックスタート
まず PdfFactory をインジェクトして Document を構築し、PdfResponse で返します。バックグラウンドで PDF を生成する場合は、GeneratePdfMessage を Messenger トランスポートにディスパッチします。
ステップ 1 — コントローラーで PDF を生成する
「ステップ 1 — コントローラーで PDF を生成する」という見出しのセクションまず NextPDF\Symfony\Service\PdfFactory をインジェクトします。その create() メソッドは、新しい NextPDF\Core\Document を返します。設定済みのデフォルト値(作成者、著者、言語)はあらかじめ適用されています。そのドキュメントを 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() は Symfony\Component\HttpFoundation\Response を返します。これには Content-Type: application/pdf、attachment ディスポジション、Content-Length、およびバンドルの固定セキュリティヘッダーが含まれます。Symfony では、標準の Response クラスとそのヘッダーモデルが文書化されています(https://symfony.com/doc/current/components/http_foundation.html)。
ステップ 2 — PDF をインラインで表示する
「ステップ 2 — PDF をインラインで表示する」という見出しのセクションPDF をダウンロードさせる代わりにブラウザーで表示するには、inline() を使用します。
return PdfResponse::inline($doc, 'preview.pdf');ディスポジションは inline になります。その他のヘッダーはすべて変わりません。
ステップ 3 — 大きな PDF をストリーミングする
「ステップ 3 — 大きな PDF をストリーミングする」という見出しのセクション大きなドキュメントでは、ストリーミング版が PDF を 64 KB のチャンクで出力します。これにより、ピークメモリを削減できます。これらのメソッドは Symfony\Component\HttpFoundation\StreamedResponse を返し、Content-Length を省略します。
return PdfResponse::streamDownload($doc, 'annual-report.pdf');streamInline() はインライン表示に対応するメソッドです。Symfony では StreamedResponse のコールバックコントラクトが文書化されており、これは出力をフラッシュする void の callable です(https://symfony.com/doc/current/components/http_foundation.html)。
ステップ 4 — PDF を非同期で生成する
「ステップ 4 — PDF を非同期で生成する」という見出しのセクションお使いの環境に symfony/messenger がインストールされている場合、生成処理をリクエストスレッドから切り離すことができます。
4a — ビルダーを実装する
「4a — ビルダーを実装する」という見出しのセクションまず NextPDF\Symfony\Message\PdfBuilderInterface を実装します。ハンドラーは、設定済みの新しい Document を渡します。また、メッセージから取り出したシリアライズ可能なコンテキストも渡します。
<?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 — ロケーターにビルダーを登録する
「4b — ロケーターにビルダーを登録する」という見出しのセクションハンドラーは、クラス名をキーとする PSR-11 サービスロケーターからビルダーを resolve(解決)します。そのため、登録済みのビルダーだけにアクセスできます。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'ハンドラーは、クラス文字列の ID によってロケーターにビルダーを要求します。PSR-11 におけるコンテナー識別子は、エントリーを一意に識別する文字列です(PSR-11 §1.1.2)。
4c — メッセージをディスパッチする
「4c — メッセージをディスパッチする」という見出しのセクションまず Symfony\Component\Messenger\MessageBusInterface をインジェクトし、メッセージをディスパッチします。
<?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 は readonly の DTO です。そのコンストラクターは、空の出力パス、.pdf 以外の出力パス、パストラバーサルのセグメント、ストリームラッパーのスキーム、および null バイトを拒否します。また、builderClass が構文上有効なクラス名であることも要求します。ハンドラーは書き込み前に、実行時にも出力パスを再検証します。そのため、ディスパッチ時には安全でも消費時に安全でなくなったパスは、依然として拒否されます。#[AsMessageHandler] 属性と MessageBusInterface のディスパッチコントラクトは、標準の Symfony Messenger モデルに従います(https://symfony.com/doc/current/messenger.html)。
4d — メッセージをルーティングしてワーカーを実行する
「4d — メッセージをルーティングしてワーカーを実行する」という見出しのセクション設定ファイル config/packages/messenger.yaml で、メッセージをトランスポートにルーティングします。
framework: messenger: transports: async: '%env(MESSENGER_TRANSPORT_DSN)%' routing: NextPDF\Symfony\Message\GeneratePdfMessage: async次に、ワーカーを実行します。
php bin/console messenger:consume async動作を確認する
「動作を確認する」という見出しのセクションphp bin/console debug:container --tag=container.service_locatorphp bin/console messenger:consume async --limit=1 -vv最初のコマンドは、ビルダーロケーターが登録されていることを確認します。2 番目のコマンドは、キューに入った 1 件のメッセージを消費し、ハンドラーの進行状況を出力します。
次のステップ
「次のステップ」という見出しのセクション- /integrations/symfony/configuration/ — デフォルト値、フォント、およびドキュメントサービスを調整します。
- /integrations/symfony/production-usage/ — ワーカーの安全性と高負荷時のストリーミング。
- /integrations/symfony/troubleshooting/ — 一般的な起動時および実行時の問題。
各行は、このページで行われる規範的な主張であり、ゲート付き SDO コーパスの完全な 64 桁の 16 進数 reference_id に固定されています。来歴(コーパスマニフェスト、取得トランスポート)は _sidecars/rag-citations.yaml にあります。
| 仕様 | 条項 | リファレンス ID | 主張 |
|---|---|---|---|
| PSR-11 | psr_11_container#1.1.2.p4 | コンテナーの has()/get() 識別子コントラクト |
- /integrations/symfony/overview/ — 機能の概要。
- /integrations/symfony/install/ — インストールと登録。
- /integrations/symfony/integration/ — エンドツーエンドの結線リファレンス。