PHPでregister_shutdown_functionを使ってエラーハンドリングした場合にFatal errorを無視する場合がある

PHPでregister_shutdown_functionを使ってエラーハンドリングした場合にFatal errorを無視する場合がある

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を取得してちゃんと想定通りの動きが出来るようになるのか?ということですが、出来るんですかね?