3

次の2つのPHP(5.4)スクリプトについて考えてみます。register_shutdown_functionスクリプトAが実行されたときにのみコールバックが呼び出され、スクリプトBが実行されたときに呼び出されないのはなぜですか?

スクリプトA

set_error_handler(function() {
    throw new Exception();
});
register_shutdown_function(function() {
    echo "shutdown handler invoked\n";
});

undefined();
// "shutdown handler invoked" IS displayed

スクリプトB

set_error_handler(function() {
    throw new Exception();
});
register_shutdown_function(function() {
    echo "shutdown handler invoked\n";
});

$undefined->undefined();
// "shutdown handler invoked" IS NOT displayed
4

2 に答える 2

1

これはバグです。に登録されている呼び出し可能オブジェクトset_error_handlerが例外をスローした場合、シャットダウン関数は呼び出されません。

この特定のケースでは、次の一連のイベントが発生します。

  1. 致命的でないエラーがトリガーされます(未定義の変数:未定義)
  2. ユーザーエラーハンドラが呼び出されます
  3. 例外がスローされます
  4. 致命的なエラーがトリガーされます(非オブジェクトでのメンバー関数undefined()の呼び出し)
  5. 既存の例外のため、シャットダウン機能は呼び出されません

https://bugs.php.net/61767(パッチ付き!)およびhttps://bugs.php.net/60909の既存のバグレポートに追加の詳細があります。

于 2012-07-17T03:00:19.927 に答える
0

これが私が見つけたものです。

register_shutdown_functionは終了時に呼び出されます。

$ undefined-> undefined(); $ undefinedはset_error_handlerを通過する変数として未定義であるため、E_NOTICEエラーをトリガーします。throw new Exceptionを呼び出すと、何らかの理由でphpはexitがクラッシュしたときにregister_shutdown_functionハンドラーをトリガーしません。例外をスローしたい場合は、例外関数を直接呼び出すことができます。

ダミークラスを作成して$undefinedを定義したが、undefinedというメンバー関数を作成しなかった場合、以下のようにundefined()を呼び出すのと同じように動作します。

未定義(); E_ERRORをトリガーし、shutdown_functionハンドラーのトリガーをすぐに終了します

これは、エラーハンドラを使用してさまざまな種類のエラーをキャッチする以外に、シャットダウン関数で実行できます。

function shutdown_function_handler(){
    if ($error = error_get_last()){
        switch ($error['type']){
            case E_ERROR:
            case E_USER_ERROR:
            case E_CORE_ERROR:
            case E_COMPILE_ERROR:
                echo " ERRROR:".$error['message'];
        }
    }
}
于 2012-07-15T09:09:03.483 に答える