コンテンツにスキップ

CodeIgniter 4 向け NextPDF

nextpdf/codeigniter は、CodeIgniter 固有の Services レイヤーを通じて NextPDF PDF エンジンを CodeIgniter 4 アプリケーションに接続します。コントローラー、ジョブ、コマンド内で PDF ドキュメントを構築し、CodeIgniter ネイティブの HTTP レスポンスとして返せます。

Terminal window
composer require nextpdf/codeigniter

このパッケージの composer.jsonphp >=8.4 <9.0nextpdf/core ^3.0 || ^5.2、および codeigniter4/framework ^4.6 を必須要件とします。また、 nextpdf/artisannextpdf/premium、および codeigniter4/queue を推奨しています。要件一覧、任意パッケージ、検証手順は /integrations/codeigniter/install/ で確認できます。

NextPDF は PHP 8.4 製の PDF 2.0 エンジンです。コアエンジン(nextpdf/core)はフレームワークに依存しません。HTTP、ルーティング、依存関係の配線には一切関与しません。nextpdf/codeigniter は、このエンジンを CodeIgniter 4 アプリケーションへ接続するアダプターです。アダプターを導入すれば、レジストリ、ファクトリ、レスポンス処理を自分で配線する必要はありません。

このパッケージは CodeIgniter 4 アプリケーションに次の 4 つの要素を追加します。

  • Services クラスNextPDF\CodeIgniter\Config\Services)。CodeIgniter により自動検出され、名前付きサービス fontRegistryimageRegistrydocumentFactorypdfDocumentpdftsaClient、および pdfSigner を公開します。
  • Pdf ライブラリNextPDF\CodeIgniter\Libraries\Pdf)。高レベルのコントローラー API です。使い捨ての単一ドキュメントをラップし、1 回の呼び出しでレスポンスへ変換します。
  • PdfResponse ヘルパーNextPDF\CodeIgniter\Http\PdfResponse)。インラインプレビューまたはダウンロード向けの CodeIgniter DownloadResponse を生成します。レスポンスを堅牢化する固定ヘッダー群を付与します。
  • 2 つのグローバルヘルパー関数 pdf()pdf_document()。これらは Composer の files オートロードエントリと、パッケージの Registrar を通じて登録されます。

このパッケージは、ドキュメント構築時に任意の NextPDF 拡張機能も検出します。nextpdf/artisan がインストールされ、Chrome バイナリが設定されていれば、ドキュメントで Chrome レンダラーを使用できます。NextPDF Pro がインストールされていれば、PDF/A 出力とデジタル署名を同じ Services インターフェイスから利用できます。検出は条件付きで、出力を伴わずに行われます。このパッケージが、存在しない拡張機能を要求することは決してありません。

コンテナバインディングではなく Services クラスを採用する理由

「コンテナバインディングではなく Services クラスを採用する理由」という見出しのセクション

CodeIgniter 4 には PSR-11 の依存性注入コンテナは同梱されていません。代わりに、Services ロケーターを使用します。Services ロケーターとは、フレームワークに検出される静的ファクトリメソッドを持つクラスで、各メソッドは共有インスタンスまたは新しいインスタンスのいずれかを返します。PSR-11 は、サービスロケーターパターン(オブジェクトが自身の依存関係を取得できるよう、コンテナをオブジェクトに渡すこと)を明示的に非推奨として扱っています(PSR-11 §1.3、助動詞 SHOULD NOT)。このパッケージは CodeIgniter のロケーター規約に従いながら、ロケーターのインターフェイスを最小限かつ明示的に保ちます。すべてのサービスは bool $getShared パラメーターを持つ名前付きファクトリメソッドであり、呼び出し元はコンテナのハンドルではなく具体的なオブジェクトを受け取ります。

この設計により、CodeIgniter 連携は Laravel および Symfony の連携と一貫します。各連携は、それぞれのフレームワーク固有の作法を通じて同じ論理サービスを公開します。

エントリポイント種類戻り値ライフタイム
Services::fontRegistry()サービスFontRegistryInterface共有(ウォームアップ後にロック)
Services::imageRegistry()サービスImageRegistry共有(上限付き LRU キャッシュ)
Services::documentFactory()サービスDocumentFactoryInterface共有(ステートレス)
Services::pdfDocument(false)サービスNextPDF\Core\Document呼び出しごとに新規生成
Services::pdf(false)サービスNextPDF\CodeIgniter\Libraries\Pdf呼び出しごとに新規生成
Services::tsaClient()サービス?TsaClient共有。null(TSA URL がない場合)
Services::pdfSigner(false)サービス?SignerInterface新規生成。null(署名が無効の場合)
pdf()ヘルパーPdf呼び出しごとに新規生成
pdf_document()ヘルパーDocument呼び出しごとに新規生成
PdfResponse::inline() / download()静的DownloadResponse呼び出しごと
GeneratePdfJobキュージョブディスパッチごとに 1 つ

コントローラーは 3 行で PDF を返します。Services::pdf() は、新しいドキュメントをラップする新しい Pdf ライブラリを生成します。その後、download() が CodeIgniter の DownloadResponse を生成します。

<?php
declare(strict_types=1);
namespace App\Controllers;
use CodeIgniter\HTTP\DownloadResponse;
use NextPDF\CodeIgniter\Config\Services;
final class InvoiceController extends BaseController
{
public function download(int $id): DownloadResponse
{
$pdf = Services::pdf();
$pdf->document()->addPage();
$pdf->document()->cell(0, 10, "Invoice #{$id}");
return $pdf->download("invoice-{$id}.pdf");
}
}

実行可能な完全なウォークスルーは /integrations/codeigniter/quickstart/ にあります。ルーティング、インラインプレビュー、pdf()pdf_document() ヘルパーのバリエーションについて説明します。

本番環境では、Services::pdf(false) で非共有インスタンスを要求します。単一の基底例外 NextPDF\Exception\NextPdfException をキャッチします。コアと拡張機能の失敗はすべて、この例外を継承します。エラーを握りつぶさず、コンテキストとともに失敗を記録します。

try {
$pdf = Services::pdf(false);
$pdf->document()->addPage();
$pdf->document()->cell(0, 10, "Invoice #{$id}");
return $pdf->download("invoice-{$id}.pdf");
} catch (NextPdfException $e) {
$logger->error('pdf.invoice.failed', [
'invoice_id' => $id,
'exception' => $e::class,
'message' => $e->getMessage(),
]);
return $this->response
->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR)
->setJSON(['error' => 'pdf_generation_failed', 'invoice_id' => $id]);
}

完全な本番環境向けコントローラーは /integrations/codeigniter/production-usage/ にあります。観測性のための計測、ワーカーセーフなライフタイム、非同期生成を追加します。

  • フォントレジストリと画像レジストリは、プロセスのライフタイムにわたるシングルトンです。ドキュメントが共有されることは決してありません。pdfDocumentpdf は呼び出しごとに新しいインスタンスを返すため、あるリクエストの内容が別のリクエストに漏れることはありません。Services::pdf(false)pdf() はいずれも、新しいドキュメントをラップする新しいライブラリを返します。
  • このパッケージは mbstring および zlib PHP 拡張機能を必要とします。フォントレジストリは、これらをプロセスごとに 1 回検証します。いずれかの拡張機能が存在しない場合、フォントレジストリは不足している拡張機能名を示すランタイムエラーを発生させます。
  • 任意拡張機能の挙動は、同じアプリケーションにインストールされている内容によって異なります。nextpdf/core のみが存在する場合、署名と PDF/A の処理は null を返すか、スキップされます。これらの処理が明示的にエラーを発生させることは決してありません。

この連携が、エンジン自体を超える測定可能なオーバーヘッドを追加することはありません。フォントレジストリは 1 回解析された後、ロックされます。画像レジストリは、imageCacheMb 設定(デフォルトで 50 MB)によって上限が定められた LRU キャッシュです。PDF の構築コストはアダプターではなく、コアエンジンとドキュメントの内容によって決まります。このドキュメントセットのページごとの予算は、実時間 1500 ms / ピーク 128 MB です。実際のレシピでは、フロントマターで独自の予算を設定します。

PdfResponse は、出力するすべての PDF に固定レスポンスヘッダー群 X-Content-Type-Options: nosniffX-Frame-Options: DENYContent-Security-Policy: default-src 'none'X-Robots-Tag: noindex, nofollow、および Referrer-Policy: no-referrer を付与します。ファイル名はサニタイズされ、非 ASCII 名は RFC 5987 拡張パラメーター付きで出力されます。キュージョブは、ビルダーの呼び出し可能オブジェクトを App\PdfBuilders 名前空間に制限し、出力パスを WRITEPATH/pdfs/ に限定します。完全な脅威モデルについては /integrations/codeigniter/security-and-operations/ を参照してください。

  • モジュールの検出は、Composer の PSR-4 オートロードに依存します。名前空間プレフィックスはベースディレクトリにマッピングされ、完全修飾クラス名はファイルパスにマッピングされます(PSR-4 §x1.x3)。
  • Services の設計は、PSR-11 §1.3 で論じられているロケーターのガイダンスに従います。

NextPDF core は Apache-2.0 です。デジタル署名、PDF/A アーカイブ、および Factur-X 電子請求書の埋め込みは、NextPDF Pro と NextPDF Enterprise によって提供されます。CodeIgniter パッケージは、対応するサービスメソッドを公開します。これらのメソッドは、対応する Premium パッケージが同じアプリケーションにインストールされるまで null を返します。

  • /integrations/codeigniter/install/ — パッケージのインストールと検証。
  • /integrations/codeigniter/quickstart/ — コントローラーでの最初の PDF。
  • /integrations/codeigniter/configuration/ — すべての設定キー。
  • /integrations/codeigniter/boot-and-discovery/ — CodeIgniter が Services クラスを見つける仕組み。
  • /integrations/codeigniter/integration/ — 配線リファレンスとスモークテスト。