📝
【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のインストール手順は省く
config/dompdf.php
の再生成
1. - 旧バージョンからのバージョンアップしていた場合、
config/dompdf.php
が旧仕様のままの可能性があるので再生成する
php artisan vendor:publish --provider="Barryvdh\DomPDF\ServiceProvider"
load_font.php内の$fontDir
に絶対パスを指定
2. 自分の環境では以下のようにフォントファイルのパス設定していたので
// 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';
load_font.php
をデプロイコンテナ内で実行
3. 以下のコマンドで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