compat-legacy のトラブルシューティング
移行時の問題の多くは、いくつかのパターンに分類できます。以下では、それぞれの症状、原因、修正方法を示します。特定のメソッドについて判断に迷う場合は、/integrations/tcpdf-compat/method-coverage/ およびリポジトリ内の信頼できるマトリクス docs/TCPDF_COVERAGE.md を参照してください。
以前は PDF エラーでプロセスが停止していたが、現在は例外がスローされる
「以前は PDF エラーでプロセスが停止していたが、現在は例外がスローされる」という見出しのセクション症状。 以前はレンダリングの失敗時に停止していたコードが、現在は未捕捉の RuntimeException をスローし、リクエストまたはジョブのエラーとして表面化します。
原因。 レガシー TCPDF の Error() は die() を呼び出します。アダプターはその代わりに RuntimeException をスローします。これは設計上の動作であり、失敗を観測可能にするためです。
修正方法。 レンダリングのエントリーポイントを try/catch でラップし、例外を自分のエラーコントラクトにマッピングしてください。die() の動作を復元しないでください。/integrations/tcpdf-compat/production-usage/ の § Failure handling を参照してください。
new \TCPDF() が依然として本物の TCPDF ライブラリに解決される
「new \TCPDF() が依然として本物の TCPDF ライブラリに解決される」という見出しのセクション症状。 LegacyBootstrap::enableAliases() を有効にしたにもかかわらず、出力が依然としてレガシー TCPDF のように見える、または動作が変わりません。
原因。 enableAliases() は、その名前のクラスがまだ存在しない場合に限りエイリアスを登録します。tecnickcom/tcpdf が依然としてオートロード可能で、その \TCPDF が先に読み込まれると、エイリアスはスキップされ、コードはレガシー TCPDF を使い続けます。
修正方法。 移行中は、各呼び出し箇所を曖昧にしないために、ファイルごとに明示的なインポート(use NextPDF\Compat\Tcpdf\TCPDF;)を使うことをおすすめします。監査が通過したら tecnickcom/tcpdf を削除してください(/integrations/tcpdf-compat/migration/ の Stage 5 を参照)。同一プロセス内で、グローバルエイリアスを有効にしたまま両方のライブラリを実行しないでください。
メソッドは「動作する」が、渡したパラメーターが無視される
「メソッドは「動作する」が、渡したパラメーターが無視される」という見出しのセクション症状。 呼び出しは成功して PDF は生成されますが、渡したオプション(画像リンク、配置、DPI、ブックマークの色など)が反映されません。
原因。 そのメソッドはサイレント無視セットに含まれています。ソース互換性のためにパラメーターを受け取りますが、その後に破棄します。これはバグではなく、文書化された動作です。/integrations/tcpdf-compat/method-coverage/ の §2 を参照してください。
修正方法。 strict モードの監査を実行し、そのような呼び出しをすべて見つけてください。
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\Exception\TcpdfNotImplementedException;use NextPDF\Compat\Tcpdf\TCPDF;
$pdf = new TCPDF();$pdf->setStrictMode(true);$pdf->AddPage();$pdf->SetFont('helvetica', '', 12);
try { $pdf->Image('logo.png', 10, 10, 50, 0, '', 'https://example.com');} catch (TcpdfNotImplementedException $e) { // Message lists every ignored parameter and a migration hint. echo $e->getMessage(), "\n";}その後、/integrations/tcpdf-compat/migration/ の Stage 4 と同様に、パラメーターを削除するか、モダン API($pdf->getDocument())経由で表現し直してください。
MultiCell() の戻り値が常に 1 になる
「MultiCell() の戻り値が常に 1 になる」という見出しのセクション症状。 MultiCell() の戻り値で分岐するコード(たとえば、使用した高さや行数を計算するコード)が正しく動作しません。
原因。 アダプターの MultiCell() は、レンダリングされた cell/line 数ではなく、互換性維持のためのプレースホルダー 1 を返します。Write() も同様に 0 を返します。
修正方法。 これらの戻り値に基づいて分岐しないでください。レンダリング後の高さが必要な場合は、getStringHeight() / getNumLines() から計算するか、そのロジックをモダン API に移してください。
setPDFVersion('1.4') を呼んでも PDF 1.4 ファイルが生成されない
「setPDFVersion('1.4') を呼んでも PDF 1.4 ファイルが生成されない」という見出しのセクション症状。 古い PDF バージョンを要求しても、出力は依然として PDF 2.0 のままです。
原因。 出力は常に PDF 2.0(ISO 32000-2)です。setPDFVersion() は該当なしセットに含まれており、アダプターは通知を出力して処理を続行します。
修正方法。 その呼び出しを削除してください。下流のコンシューマーが古い PDF バージョンを必要とする場合は、そのコンシューマー側の制約を別途解決してください。アダプターは出力をダウングレードできません。
setSignature() が何もせず、PDF に署名されない
「setSignature() が何もせず、PDF に署名されない」という見出しのセクション症状。 証明書を指定して setSignature() を呼び出しても、出力 PDF に署名がありません。
原因。 setSignature() は、このアダプターを介したコアエンジンでは未実装です。デフォルトモードでは何もせず、strict モードでは例外をスローします。
修正方法。 署名には、商用の NextPDF エディションとモダンな署名 API が必要です。/integrations/tcpdf-compat/security-and-operations/ の § Digital signatures を参照してください。レガシーの setSignature() 呼び出しで何かに署名されることを期待しないでください。
Output() が HTTP レスポンスまたはワーカー出力を破損させた
「Output() が HTTP レスポンスまたはワーカー出力を破損させた」という見出しのセクション症状。 HTTP レスポンスにバイナリの文字化けが含まれる、またはワーカーログが PDF バイトで汚染されます。
原因。 レスポンスを自分で制御しているコンテキストで、出力ストリームへ書き込む出力先(I/D)を使用しました。アダプターはレガシー TCPDF のようにバッファへ エコー出力しません が、I/D は依然としてエンジン側の出力を発生させます。
修正方法。 自分で制御するワーカーやハンドラーでは、ファイルに書き込む場合は Output($path, 'F') を、バイトを取得して自分で出力する場合は Output($name, 'S') を使用してください。出力先のマッピング(大文字小文字を区別せず、前後の空白を除去)は、tests/Unit/Compat/Tcpdf/Bridge/OutputBridgeTest.php でアサートされています。
| コード | 戻り値 | 副作用 |
|---|---|---|
S | PDF バイト(%PDF…) | なし |
F | 空文字列 | ファイルへの書き込み |
E | base64 の MIME ボディ | なし |
FI / FD | 空文字列 | ファイルへの書き込み後、エンジン出力 |
I / D / 不明 | 空文字列 | エンジン出力(インライン/ダウンロード) |
切り替え後、バイト単位での PDF アサーションが失敗する
「切り替え後、バイト単位での PDF アサーションが失敗する」という見出しのセクション症状。 生の PDF バイトを比較するスナップショットテストが、広範囲で失敗します。
原因。 エンジンは独立した PDF 2.0 実装です。委譲されたメソッドでは表示上の出力に互換性がありますが、バイト列は異なります。これは想定どおりの動作です。
修正方法。 レンダリングされたコンテンツ(抽出したテキスト)、構造(ページ数、ページサイズ)、またはスモークチェック(str_starts_with($bytes, '%PDF'))でアサートするように、ベースラインを取り直してください。/integrations/tcpdf-compat/migration/ の Stage 4 を参照してください。
レガシーの K_* / PDF_* 定数の値が間違っている
「レガシーの K_* / PDF_* 定数の値が間違っている」という見出しのセクション症状。 定数で設定したカスタムパスやデフォルト値が反映されません。
原因。 アダプターは、定数がまだ定義されていない場合にのみ自動定義し、その処理を最初の構築時に行います。最初のアダプターが構築された 後 に define() が実行されると、すでにアダプターのデフォルト値が優先されています。
修正方法。 カスタムの K_* / PDF_* 定数はすべて、アダプターインスタンスを作成する前にブートストラップで定義してください。/integrations/tcpdf-compat/configuration/ の § Configuration resolution order を参照してください。
構築時にエンジンのバージョンが一致しない
「構築時にエンジンのバージョンが一致しない」という見出しのセクション症状。 依存関係の更新後に構築が失敗する、または予期しない動作をします。
原因。 アダプターは nextpdf/core ^3.0 を必要とします。その範囲外に解決されたコアバージョンはサポートされません。
修正方法。 composer show nextpdf/core を実行し、エンジンを ^3.0 に固定してください。/integrations/tcpdf-compat/install/ の § Verify the engine version を参照してください。
診断クイックリファレンス
「診断クイックリファレンス」という見出しのセクション| 質問 | 参照先 |
|---|---|
| ここでメソッド X は実際に何をするのか? | /integrations/tcpdf-compat/method-coverage/、docs/TCPDF_COVERAGE.md |
| どの呼び出しでパラメーターが失われるのか? | strict モード監査(このページ、/integrations/tcpdf-compat/migration/) |
| エラー時にプロセスが停止しなかったのはなぜか? | /integrations/tcpdf-compat/security-and-operations/ の § Hardened behaviors |
| 出力が署名されない/PDF/A でないのはなぜか? | /integrations/tcpdf-compat/security-and-operations/ |
| エイリアスと明示的インポートの競合 | このページ。/integrations/tcpdf-compat/boot-and-discovery/ |
- /integrations/tcpdf-compat/migration/ — 上記のほとんどを未然に防ぐ段階的な移行
- /integrations/tcpdf-compat/method-coverage/ — メソッドごとの動作リファレンス
- /integrations/tcpdf-compat/boot-and-discovery/ — エイリアス登録と競合回避
docs/TCPDF_COVERAGE.md— 信頼できるカバレッジマトリクス