set_error_handler
って何?
この辺読んでね。
- PHP: set_error_handler - Manual
- set_error_handler と ErrorException を組み合わせると幸せになるかも - Qiita
- お前は PHP 7 における Fatal Error / Catchable Fatal Error / Error / ErrorException / Exception の違いを言えるか? - Qiita
set_error_handler
にまつわる杞憂
ありがちな心配?
- ライブラリ側で勝手にこれ使うと,元のアプリケーション側で設定されてるハンドラを吹き飛ばしてしまうんじゃ?
-
restore_error_handler
を呼んでも,結局エラーハンドラが無かった状態に戻るだけでは?
exif_*ってデータ次第でエラー発生するしエラーハンドラ使いたいけどライブラリ関数側で使うとなぁ…もう@演算子でいいや…
function read_image_metadata(string $filename)
{
if (false === $type = @exif_imagetype($filename)) {
throw new \RuntimeException(error_get_last()['message']);
}
if ($type !== IMAGETYPE_JPEG) {
return [];
}
if (false === $data = @exif_read_data($filename)) {
throw new \RuntimeException(error_get_last()['message']);
}
return $data;
}
そんなことはない!
set_error_handler
はスタッカブルであるため,リストアするとちゃんと直前に設定されていたエラーハンドラに戻してくれる。
finallyで自動的にリストアさせる
function read_image_metadata(string $filename)
{
set_error_handler(function($severity, $message) {
throw new \RuntimeException($message);
});
try {
$type = exif_imagetype($filename);
if ($type !== IMAGETYPE_JPEG) {
return [];
}
return exif_read_data($filename);
} finally {
restore_error_handler();
}
}
若干関数呼び出しのオーバーヘッドがあるが,書きやすくすることも可能だ。
関数で共通化する
function handle_error(callable $function, ...$args)
{
set_error_handler(function($severity, $message) {
throw new \RuntimeException($message);
});
try {
return $function(...$args);
} finally {
restore_error_handler();
}
}
function read_image_metadata(string $filename)
{
return handle_error(function () use ($filename) {
$type = exif_imagetype($filename);
if ($type !== IMAGETYPE_JPEG) {
return [];
}
return exif_read_data($filename);
});
}