PHP 7以降では、PHPのエラーは基本的にErrorクラスとして扱われ、try-catchブロックで捕まえることができるようになりました。(Catchable Fatal Error)
ちなみにPHP 7では下記の2つのクラスがThrowableクラスを継承しており、両方捕まえるときは、try-catchブロックでThrowableをcatchするように書けばOKです。
- Exception
- Error
ただし、一部のFatal Error(例: Memory Exhausted Error)はtry-catchブロックで捕まえることができません。
Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 9792 bytes) in ....
この場合は、register_shutdown_functionを使って、PHPのプログラムが終了したときにエラー処理をするしかなさそうです。
register_shutdown_functionとerror_get_lastを使ってエラー処理をする関数のコード例を示します。
<?php // PHPのError定数 => 文字列表現の連想配列 const ERROR_CODE_TO_STRING = [ E_ERROR => 'E_ERROR', E_WARNING => 'E_WARNING', E_PARSE => 'E_PARSE', E_NOTICE => 'E_NOTICE', E_CORE_ERROR => 'E_CORE_ERROR', E_CORE_WARNING => 'E_CORE_WARNING', E_COMPILE_WARNING => 'E_COMPILE_WARNING', E_USER_ERROR => 'E_USER_ERROR', E_USER_WARNING => 'E_USER_WARNING', E_USER_NOTICE => 'E_USER_NOTICE', E_STRICT => 'E_STRICT', E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR', E_DEPRECATED => 'E_DEPRECATED', E_USER_DEPRECATED => 'E_USER_DEPRECATED', ]; // $catchLevelにキャッチしたいエラーレベルの定数を渡します。 // 需要があるかわかりませんが、bit演算の&を使って捕まえるべきか判定しているので、 // E_ALLを渡すとE_NOTICEエラーも捕まえられます。 function catchError($catchLevel) { register_shutdown_function(function() use($catchLevel){ $error = error_get_last(); if(empty($error)) { return; } $shouldCatch = $error['type'] & $catchLevel; if($shouldCatch) { $error['typeString'] = ERROR_CODE_TO_STRING[$error['type']] ?? ''; // $error containus type message, file, line information. // do something nice... echo json_encode($error, JSON_PRETTY_PRINT); // ここでメモリを大量に消費するような処理を書くと再度、Memory Exhausted Errorになってしまうので注意。 // とはいえ、memory_limitの設定容量が十分あり、常識的な処理であれば、 // エラー部分の処理でメモリ不足を心配する必要はありません。 } }); }
コメント