【PHP】Dompdf で画像が読み込まれない時のデバッグ方法

  • 2022年1月24日
  • 2022年1月24日
  • PHP

 Dompdf は PHP 上で HTML を元に PDF ファイルを生成してくれるライブラリです。CSS についてはブラウザほど高機能ではありませんが、HTML によって楽に整った PDF を生成できます。
dompdf/dompdf: HTML to PDF converter for PHP
 Dompdf で img タグ等によって画像を埋め込む時、しばしばなかなか解決しない時があります。IDE から見えている設定やパスの書き方を変えても”Image not found or type unknown”と書かれた箱が画像の代わりに出力されるばかりです。これの原因の把握する方法を紹介します。
 ここで扱う dompdf のバージョンは v1.1.1 です。
 まず一番に見るべきなのはグローバル変数の $_dompdf_warningsです。
Usage · dompdf/dompdf Wiki

/** dompdf の警告エラーを表示 */
function dumpDompdfLog(){
   // スコープ
   global $_dompdf_warnings;
   
   var_dump($_dompdf_warnings);
/** 出力例
array:3 [
  0 => "file_get_contents(): Passing null to parameter #2 ($use_include_path) of type bool is deprecated"
  1 => """
    Permission denied on /work/backend/public/cal2.png. The file could not be found under the paths specified by Options::chroot. \n
     /work/backend/public/cal2.png
    """
  2 => "file_get_contents(): Passing null to parameter #2 ($use_include_path) of type bool is deprecated"
]
*/
}

 Dompdf は可能な限り処理を進める方針で作られています。これは少々の問題があってもそれらしい PDF が出力されるという点で便利ですが、エラーが目立たないという欠点があります。こういった時、エラーはログファイル等のどこかしらに貯められます。Dompdf の場合、こういった致命的でないエラーは $_dompdf_warnings というグローバル変数に格納されていきます。これを dump することで何が起きているのか正確にわかります。Dompdf の PDF 上に出力される画像エラーはエラー内容に関わらず”Image not found or type unknown”ですが、実際には Permission denied ということもあります。

 次に見るべきは画像エラーの詳しい内容です。これは \Dompdf\Image\Cache::resolve_url メソッドの中を見るといいです。resolve_url は画像 URL を解決するためのメソッドで、この中で画像を読み込めない時のエラーの処理も行います。このメソッドは大きく try catch でくくられており、例外として投げられたエラーを catch ないでざっくばらんにまとめています。このざっくばらんを解体して細かく見ることでエラー原因がわかりやすくなります。
dompdf/Cache.php at master · dompdf/dompdf

        } catch (ImageException $e) {
            // $_dompdf_warnings で見れないエラーの細かい部分を表示
            var_dump($e);
            // スタックトレースの出力
            var_dump($e->getTrace());
            if ($tempfile) {
                unlink($tempfile);
            }
            $resolved_url = self::$broken_image;
            $type = "png";
            $message = self::$error_message;
            Helpers::record_warnings($e->getCode(), $e->getMessage() . " \n $url", $e->getFile(), $e->getLine());
            self::$_cache[$full_url] = $resolved_url;
        }
>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG