PHPでFatal Errorsが起きた場合に画面が真っ白になるのを防ぐ手段としてregister_shutdown_functionを使う方法というのが一般的に使われています
~~~
//On production environments
error_reporting(0);
function fatalErrorHandler() {
# Getting last error
$error = error_get_last();
# Checking if last error is a fatal error
if(($error[‘type’] === E_ERROR) || ($error[‘type’] === E_USER_ERROR)|| ($error[‘type’] === E_USER_NOTICE)) {
# Here we handle the error, displaying HTML, logging, …
echo “ERRORnr : ” . $error[‘type’]. ” |Msg : “.$error[‘message’].” |File : “.$error[‘file’]. ” |Line : ” . $error[‘line’];
}else {
echo “no error where found ” ;
}
}
# Registering shutdown function
register_shutdown_function(‘fatalErrorHandler’);
// let force a Fatal error — function does not exist
functiontest();
~~~
引用元
これを実行すると画面上にエラーが表示されます
ERRORnr : 1 |Msg : Call to undefined function functiontest() |File : test.php |Line : 27
ところがこんなふうに書くとどうなると思いますか?
~~~
function fatalErrorHandler() {
# Getting last error
$error = error_get_last();
# Checking if last error is a fatal error
if(($error[‘type’] === E_ERROR) || ($error[‘type’] === E_USER_ERROR)|| ($error[‘type’] === E_USER_NOTICE)) {
# Here we handle the error, displaying HTML, logging, …
echo “ERRORnr : ” . $error[‘type’]. ” |Msg : “.$error[‘message’].” |File : “.$error[‘file’]. ” |Line : ” . $error[‘line’];
}else {
echo “no error where found ” ;
}
}
function functiontest() {
functiontest2();
}
# Registering shutdown function
register_shutdown_function(‘fatalErrorHandler’);
register_shutdown_function(‘functiontest’);
~~~
結果はno error where found と表示されます
functiontest2が存在しないことはなぜか無視されます
ちなみにini_set(‘display_errors’ , 1);すればFatal errorが表示されるが最後(functiontest2の前)まで実行されるという不思議な挙動になります
~~~
Fatal error: Call to undefined function functiontest2() in test.php on line 19
~~~
register_shutdown_functionは順番に実行されるのでこう書き換えると
~~~
function fatalErrorHandler() {
# Getting last error
$error = error_get_last();
# Checking if last error is a fatal error
if(($error[‘type’] === E_ERROR) || ($error[‘type’] === E_USER_ERROR)|| ($error[‘type’] === E_USER_NOTICE)) {
# Here we handle the error, displaying HTML, logging, …
echo “ERRORnr : ” . $error[‘type’]. ” |Msg : “.$error[‘message’].” |File : “.$error[‘file’]. ” |Line : ” . $error[‘line’];
}else {
echo “no error where found ” ;
}
}
function functiontest() {
functiontest2();
}
register_shutdown_function(‘functiontest’);
# Registering shutdown function
register_shutdown_function(‘fatalErrorHandler’);
echo 1;
~~~
echo 1 が出力されますが no error where found とは表示されなくなります
もちろんini_set(‘display_errors’ , 1);すればFatal errorが表示されます
わけがわかりませんね(゚∀゚)
知りたいのは書き換えた2つのようにエラーハンドリング以外の場合にregister_shutdown_functionを使ってFatal errorを取得してちゃんと想定通りの動きが出来るようになるのか?ということですが、出来るんですかね?
コメント
シャットダウン関数 functiontest で fatal error になったためその次に呼ばれるはずだったシャットダウン関数 fatalErrorHandler が呼ばれなかった、からだと思いますよ?
register_shutdown_function はエラーハンドラを登録するのではなく、スクリプトの終了時に実行される関数を登録するもので、シャットダウン関数の中で fatal error が発生したり exit で終了したりすると後続のシャットダウン関数は実行されません。
公式サイトにも載っている書き方ですし、(http://php.net/manual/ja/function.register-shutdown-function.php#85727)、FuelPHP内でも使われているのでこの使い方どうなの?って思って書いたので、エラーハンドラとして使うべきではないということでいいんでしょうか?