コンテンツにスキップ

Symfony 開発者ガイド

Symfony パッケージはサービスファーストです。PdfFactory をインジェクトし、ドキュメントごとに create() を呼び出し、非同期生成には Messenger ビルダーを使用します。呼び出しのたびに新しいドキュメントが返されるため、ファクトリーはコンテナサービスとして扱えます。

コントローラー、サービス、Messenger ハンドラー、またはバンドルレベルの拡張ポイントを nextpdf/symfony を軸に設計するときは、このガイドを参照してください。

レイヤー所有者責務ここに置かないもの
コントローラーアプリケーションリクエスト認可、入力収集、PdfResponse の返却。ユースケース間で共有される PDF レイアウト。
アプリケーションサービスアプリケーションドメインデータの読み込みとビルダー選択。Symfony コンテナコンパイラーのロジック。
ビルダーサービスアプリケーション同期またはキュー実行でドキュメントを構築するための PdfBuilderInterface 実装。リクエストオブジェクト、エンティティマネージャー、またはシリアライズできないコンテキスト。
Symfony バンドルnextpdf/symfonyサービス、設定ツリー、オプションの拡張パス、レスポンスヘルパー、Messenger DTO の登録。テナント固有のストレージポリシー。
コアエンジンnextpdf/nextpdfドキュメントの作成とシリアライズ。Symfony のレスポンスまたは Messenger の動作。
ステージ動作開発者のアクション
バンドルのブートNextPdfBundle::build() によるオプション拡張機能検出の登録。Symfony によるバンドル検出、または bundles.php への登録。
設定の読み込みNextPdfExtension::load() による nextpdf: 設定の処理とサービス定義の読み込み。明示的で環境を考慮した設定。
ファクトリーの使用PdfFactory::create() による設定済みの新規ドキュメントの返却。ドキュメントをサービスに保存しないこと。
コントローラーの出力PdfResponse による完成済みドキュメントのレスポンス変換。ヘッダーを手動で組み立てず、ヘルパーを使用すること。
Messenger のディスパッチGeneratePdfMessage によるビルダークラス、出力パス、シリアライズ可能なコンテキストの伝達。最小限でスカラー値中心のコンテキスト。
メッセージの処理GeneratePdfHandler によるサービスロケーターからのビルダーの解決とドキュメント保存。決定論的かつ冪等なビルダー。
パス目的
src/Pdf/Builder/*PdfBuilderInterface を実装するサービス。
src/Pdf/Data/*ビルダーコンテキスト用の小さな DTO または配列。
src/Pdf/Storage/*ストレージルートの選択と出力ファイル名のポリシー。
src/Controller/*同期レスポンスのエントリーポイント。
tests/Pdf/*ビルダー、レスポンス、Messenger、設定のテスト。

静的ヘルパー関数よりもビルダーサービスを優先してください。ビルダーサービスは、タグ付け、デコレーション、テスト、Messenger からの利用が容易です。

<?php
namespace App\Pdf\Builder;
use NextPDF\Core\Document;
use NextPDF\Symfony\Message\PdfBuilderInterface;
final readonly class InvoicePdfBuilder implements PdfBuilderInterface
{
public function build(Document $document, array $context): Document
{
$document->setTitle((string) $context['title'])
->addPage()
->writeHtml((string) $context['html']);
return $document;
}
}
<?php
namespace App\Controller;
use App\Pdf\Builder\InvoicePdfBuilder;
use NextPDF\Symfony\Http\PdfResponse;
use NextPDF\Symfony\Service\PdfFactory;
final readonly class InvoiceController
{
public function __invoke(
PdfFactory $factory,
InvoicePdfBuilder $builder,
) {
$document = $builder->build($factory->create(), [
'title' => 'Invoice 1234',
'html' => '<h1>Invoice 1234</h1>',
]);
return PdfResponse::download($document, 'invoice-1234.pdf');
}
}

コントローラーのコンテキストは小さく保ってください。ビルダーが多数のドメインオブジェクトを必要とする場合は、オーケストレーションをアプリケーションサービスへ移し、DTO または正規化済みの配列をビルダーに渡してください。

GeneratePdfMessage はディスパッチ前にビルダークラスと出力パスを検証します。ハンドラーは実行時にもパスを再検証します。

<?php
use App\Pdf\Builder\InvoicePdfBuilder;
use NextPDF\Symfony\Message\GeneratePdfMessage;
$bus->dispatch(new GeneratePdfMessage(
builderClass: InvoicePdfBuilder::class,
outputPath: $projectDir . '/var/pdfs/invoice-1234.pdf',
builderContext: [
'title' => 'Invoice 1234',
'html' => '<h1>Invoice 1234</h1>',
],
));

Doctrine エンティティ、オープンストリーム、クロージャ、リクエストオブジェクト、サービスオブジェクトを builderContext に含めないでください。

拡張ポイント用途制約
PdfFactory サービスのデコレーションドキュメントがコントローラーに到達する前のアプリケーションデフォルトの適用。新しいドキュメントのセマンティクス維持。
PdfBuilderInterfaceキュー実行または再利用可能なドキュメントビルダーの定義。Document の返却。
OptionalExtensionPassコンパイル時のオプション Artisan または Premium 機能の有効化。利用可否はリクエスト状態ではなく、コンテナのコンパイル状態に基づくこと。
Symfony 設定ツリーデフォルト、PDF/A、レンダラー設定、署名、TSA、Messenger。無効な設定によるコンテナビルド時の失敗。
GeneratePdfHandler サービスの配線キューされたメッセージから到達可能なビルダーの制限。承認済みビルダーサービスのみを公開するサービスロケーター。
  1. 決定論的な入力を受け取るビルダーサービスを追加します。
  2. コントローラーまたはサービスで PdfFactory::create() を使用します。
  3. ファイル名、コンテンツタイプ、ヘッダーに関するレスポンステストを追加します。
  4. 同じドキュメントを非同期で生成する必要がある場合は、ビルダーを Messenger 用に登録します。
  5. クラス名、出力パス、コンテキストの形状について、無効なメッセージのテストを追加します。
  6. 最小構成と本番構成でのコンテナコンパイルテストを追加します。
  7. 本番環境と同じ PHP 設定で、レンダリング時間とメモリを測定します。
障害処理すべき場所推奨される対応
無効な設定コンテナコンパイル。トラフィックがアプリに到達する前にデプロイを失敗させること。
ビルダーサービスの欠落Messenger ハンドラーのテストとサービスタグ。メッセージの失敗化と担当チームへの通知。
安全でない出力パスメッセージコンストラクターとストレージポリシー。ディスパッチ前の拒否と、多層防御としてのハンドラー検証の維持。
オプション拡張機能の利用不可コンパイラーパスとファクトリーの動作。オプション機能の無効化、またはインストールの明示化。
サービスの変換またはレンダリングの失敗ビルダーの境界。ユースケースに文書化されたフォールバックがない限り、フェイルクローズすること。
関心事デフォルトオーバーライドする時期
ファクトリーのライフタイムコンテナサービス。維持すること。ファクトリーはドキュメントを作成するだけなので安全です。
ドキュメントのライフタイム1 つの作業単位。リクエストやメッセージをまたいで共有しないこと。
出力パスの検証メッセージコンストラクターとハンドラー。アプリケーションコードでのテナントまたはストレージルート制約の追加。
レスポンスのファイル名document.pdfサニタイズ済みビジネス識別子によるオーバーライド。
Messenger のトランスポートasyncPDF 処理が重い場合の専用トランスポートの使用。
  • コンテナテストは最小構成と本番構成でバンドルをコンパイルします。
  • レスポンステストはセキュリティヘッダーとファイル名の取り扱いを検証します。
  • Messenger テストは無効なパスと無効なビルダークラス名がディスパッチ前に失敗することを検証します。
  • ハンドラーテストは実際のビルダーサービスと一時的な出力ディレクトリを使用します。
  • ビルダーテストは代表的なドキュメントをレンダリングし、本番に近いファイルシステム権限で保存します。
  • オプション拡張機能のテストは、Artisan が利用できない場合、Premium が利用できない場合、設定された PDF/A プロファイルの動作を網羅します。