コンテンツにスキップ

CodeIgniter 4 における NextPDF のトラブルシューティング

以下の各症状は、パッケージまたはフレームワークのソースで検証済みの原因に対応しています。いずれにも具体的な対処方法を示しています。

CodeIgniter はサービスを解決する際、ディスカバリーで見つかった Config\Services クラスを走査し、一致するメソッドを探します。null が返された場合、フレームワークがパッケージの Services クラスを一度もディスカバリーしていないことを意味します。

原因と対処方法は次のとおりです。

  • 自動ディスカバリーが無効になっている。 ホストアプリケーションで Config\Modules::$discoverInComposer = false が設定されている場合があります。その場合は、nextpdf/codeigniter$composerPackages['only'] に追加します。ディスカバリーが Composer パッケージを走査するのは、このフラグが true の場合のみです。
  • オートローダーが古くなっている。 Composer は名前空間プレフィックス NextPDF\CodeIgniter\ をそのベースディレクトリにマッピングします。古いクラスマップでは、そのクラスが見つからなくなることがあります(PSR-4 §x1.x3)。composer dump-autoload を実行してください。
  • $aliases リストが削除されている。 ディスカバリーは Config\Modules::$aliases 内のエントリーに対してのみ実行されます。パッケージには services が必要で、ヘルパーには registrars が必要です。両方のエントリーを復元してください。

ヘルパーは、パッケージの Composer files オートロードエントリーと、パッケージの Registrar の 2 つの経路で登録されます。未定義関数エラーは、files エントリーが読み込まれていないことを意味します。

  • composer dump-autoload を実行して、files オートロードリストを再構築します。
  • nextpdf/codeigniter エントリーが vendor/composer/autoload_files.php に表示されていることを確認します。
  • 回避策として、Services::pdf(false) または Services::pdfDocument(false) を直接呼び出します。これらのヘルパーは、それぞれの呼び出しに対する薄いラッパーです。

BaseConfig はオーバーライドを解決する際、小文字の短いクラス名をプレフィックスとして使用します。クラスは NextPdf なので、プレフィックスは nextpdf です。nextPdf でも NextPdf でもありません。

  • 正しいのは nextpdf.fontsPath であり、nextPdf.fontsPath ではありません。
  • ネストされたキーはドットで指定します。たとえば nextpdf.signature.certificate のように指定します。
  • 完全修飾形式の NextPDF\CodeIgniter\Config\NextPdf.fontsPath も使用できます。

対象の NextPdf クラスを拡張し、部分的な配列を代入すると、配列全体が置き換えられます。そのため、オーバーライド対象の配列ではすべてのキーを指定してください。配列全体の例については、/integrations/codeigniter/configuration/ を参照してください。

フォントレジストリは、プロセスごとに一度だけ mbstringzlib を検証します。不足している拡張機能の名前を添えて、このエラーを発生させます。指定された拡張機能をランタイムの PHP にインストールするか有効化してください。その後、ワーカーまたは PHP-FPM プールを再起動してください。

フォントレジストリは、fontsPath がストリームラッパー(://)または NULL バイトを含む場合に拒否します。fontsPath には通常のファイルシステムパスを設定してください。php://phar://、または同様のラッパー形式のパスを指定しないでください。

PdfResponse はファイル名をサニタイズします。検証済みの動作は次のとおりです。

  • 空、または空白だけのファイル名は document.pdf になります。
  • 拡張子 .pdf(または .PDF)のない名前には、.pdf が付加されます。既存の .PDF はそのまま保持されます。
  • 非 ASCII の名前では、ASCII フォールバック RFC 5987 の filename*=UTF-8''… パラメーターが生成されます。そのため、最新のブラウザーでは元の名前が表示されます。これは想定どおりの動作であり、バグではありません。
  • パス区切り文字、NULL バイト、CR/LF は除去されます。

すべての PdfResponse レスポンスには、X-Content-Type-OptionsX-Frame-OptionsContent-Security-PolicyX-Robots-TagReferrer-Policy が付与されます。クライアント側でこれらが存在しない場合は、下流のプロキシまたはアプリケーションが除去または上書きしています。リバースプロキシの前後の両方でレスポンスを確認してください。

キューは、プッシュされたジョブ名を Config\Queue::$jobHandlers のキーと照合し、未登録の名前はすべて拒否します。ジョブを名前キーで登録し、その名前でプッシュしてください。

app/Config/Queue.php
public array $jobHandlers = ['generate-pdf' => GeneratePdfJob::class];
// dispatch
\service('queue')->push('pdf-queue', 'generate-pdf', [...]);

クラス定数 GeneratePdfJob::class をジョブ名としてプッシュすると失敗します。第 2 引数はクラス文字列ではなく、名前キーです。

ジョブは、処理を始める前にペイロードを検証します。検証済みの拒否ケースと、そのメッセージは次のとおりです。

原因メッセージの一部
builder が欠落、空、または文字列ではないnon-empty static callable string
builderApp\PdfBuilders の範囲外not allowed
builder がパターンに一致するが、呼び出し可能ではないnot a valid callable
outputPath が欠落または空non-empty string
outputPathWRITEPATH/pdfs/ の範囲外outside of allowed directory
outputPath の末尾が .pdf ではないmust end with .pdf

builder が App\PdfBuilders\<Class>::<method> の静的コーラブルになるよう、ペイロードを修正してください。出力パスが WRITEPATH/pdfs/ 内で解決され、.pdf 拡張子で終わることを確認してください。

codeigniter4/queue は、パッケージでは開発専用の依存関係です。ワーカーを実行するアプリケーションでは、これを直接 require する必要があります。

Terminal window
composer require codeigniter4/queue
  • composer show nextpdf/codeigniter — パッケージが解決されていることを確認します。
  • composer dump-autoload — ディスカバリーとヘルパーのオートロードを再構築します。
  • php spark routes — PDF ルートが登録されていることを確認します。
  • ディスカバリーを最も速く確認するには、Services::pdfDocument(false) を呼び出し、結果が Document であることをアサートするコントローラーを使います。
  • クラスからパスへのマッピング — ディスカバリーの失敗に関連します(PSR-4 Autoloader §x1.x3)。
  • /integrations/codeigniter/install/ — ディスカバリーの要件。
  • /integrations/codeigniter/configuration/ — .env のプレフィックスと配列オーバーライドのルール。
  • /integrations/codeigniter/production-usage/ — 正しいキューの登録。
  • /integrations/codeigniter/boot-and-discovery/ — ディスカバリーのシーケンス。