📝
【laravel-dompdf】Undefined array key "" のエラー対応
結論
- ビルドコンテナ内で
load_font.phpを実行していたのが原因 - デプロイコンテナ内で
load_font.phpを実行するように修正したら解決!
環境
- 環境
- Docker + CodeBuild + ECS
- ライブラリ
- Laravel 10
- laravel-dompdf v2.2
経緯
- 以下の作業中に発生
- Laravel 7 → Laravel 10へのマイグレーション中
- デプロイコンテナ単体で各種インストールからセットアップまで一括で行っていたが、ビルドコンテナ+デプロイコンテナの構成に変更
- CodeBuild上のビルドコンテナで
composer installを実行や設定ファイルの生成を行う - その後はECS上のデプロイコンテナにコピー
- CodeBuild上のビルドコンテナで
- が、laravel-dompdfでPDF機能の確認をしようとしたらエラー!なぜ!
エラー内容
{
"class": "ErrorException",
"message": "Undefined array key \"\"",
"code": 0,
"file": "/var/www/html/vendor/dompdf/dompdf/lib/Cpdf.php:4752"
}
手順
laravel-dompdfのインストール手順は省く
1. config/dompdf.phpの再生成
- 旧バージョンからのバージョンアップしていた場合、
config/dompdf.phpが旧仕様のままの可能性があるので再生成する
php artisan vendor:publish --provider="Barryvdh\DomPDF\ServiceProvider"
2. load_font.php内の$fontDirに絶対パスを指定
自分の環境では以下のようにフォントファイルのパス設定していたので
// dompdf用の設定
$this->publishes([
base_path('vendor/dompdf/dompdf/lib/fonts') => storage_path('fonts'),
], 'public');
以下のように調整した。(これはちょっと蛇足だったかもしれない、各々の環境に応じて調整が必要かも)
// 2. [Optional] Set the path to your font directory
// By default dompdf loads fonts to dompdf/lib/fonts
// If you have modified your font directory set this
// variable appropriately.
//$fontDir = "lib/fonts";
/**
* load_font.phpからstorage/fontsディレクトリへの絶対パスを設定する。
* 自分の場合はこのファイルがresources/foo/fontsに配置されていたので、dirname(__DIR__, 3)でstorage/fontsディレクトリへの絶対パスを取得する。
*/
$fontDir = dirname(__DIR__, 3) . '/storage/fonts';
3. load_font.phpをデプロイコンテナ内で実行
以下のコマンドでload_font.phpを実行すると、実行環境におけるstorage_path関数を元にフォントファイル設定を生成する
php resources/foo/fonts/load_font.php ipag resources/foo/fonts/ipag.ttf
つまりビルドコンテナ上でload_font.phpを実行していると、生成された設定ファイルがビルドコンテナ環境のstorage_pathとして生成される!←これがエラーの原因
生成されたフォント設定ファイル(installed-fonts.json)について
- ↓がビルドコンテナ上で生成した
installed-fonts.json - パスがビルドコンテナ準拠になっているので、これをデプロイコンテナにコピーしても当然動かない
- 「設定ファイルがあるが、パスが不正でフォントを読み込めない」という挙動になる
- その結果として
Undefined array key ""が発生
- その結果として
{
"ipag": {
"normal": "\/codebuild\/output\/XXXX\/src\/vendor\/dompdf\/dompdf\/lib\/fonts\/ipag",
"bold": "\/codebuild\/output\/XXXX\/src\/vendor\/dompdf\/dompdf\/lib\/fonts\/ipag",
"italic": "\/codebuild\/output\/XXXX\/src\/vendor\/dompdf\/dompdf\/lib\/fonts\/ipag",
"bold_italic": "\/codebuild\/output\/XXXX\/src\/vendor\/dompdf\/dompdf\/lib\/fonts\/ipag"
}
}
- ↓がデプロイコンテナ上で生成した
installed-fonts.json - パスが正しいので当然ちゃんと動く
{
"ipag": {
"normal": "\/var\/www\/html\/storage\/fonts\/ipag",
"bold": "\/var\/www\/html\/storage\/fonts\/ipag",
"italic": "\/var\/www\/html\/storage\/fonts\/ipag",
"bold_italic": "\/var\/www\/html\/storage\/fonts\/ipag"
}
}
余談
-
公式のissueに同じエラーが報告されているが、この人も
installed-fonts.json内のパスがおかしいのでは?という気がしている - もうちょっとエラーメッセージがわかりやすければ...
- 「設定ファイルに記述されているフォントファイルが存在しません」みたいなやつが欲しかった
Discussion