4

file1.php内:

set_error_handler('my_error_handler');
set_exception_handler('my_exception_handler');

function my_error_handler($errNo, $errStr, $errFile, $errLine, $whatever = null){
  // here ErrFile and $errLine are correct only for native funcs...
  throw New ErrorException($errStr, 0, $errNo, $errFile, $errLine);
}

function my_exception_handler($exception){
  print $exception->getLine(); // correct only for native functions
  print $exception->getFile(); // correct only for native functions
}

file2.phpの関数定義の例:

function foo($requiredArg){

}

そしてfile3.phpで、fooを呼び出します。

  foo();

生成:

2行目のfile3.phpで呼び出され、定義されたfoo()の引数1がありません...

メッセージは正しいですが、 (例外ハンドラーで) $exception->getFile()andを使用してファイルと行を取得しようとする$exception->getLine()と、呼び出された場所ではなく、foo()が定義されたファイルと行を取得します...

しかし、ネイティブPHP関数を使用すると、関数が呼び出されたファイルと行を取得できます(これが私が望むものです)。

4

2 に答える 2

2

それは単に最も近いものから始まります。

コア関数または組み込み関数を使用する場合、それらの定義はPHPのコアに含まれます。これは、定義がすぐに利用できるユーザー定義関数と比較した場合、関数の定義が利用できないことを意味します。

ユーザー定義関数のエラーを参照する関数内でdebug_backtrace();またはを実行すると、最初に関数の定義が表示され、次に関数の呼び出しが表示されます。内部関数を呼び出すと、呼び出し行のみが表示されます。PHPは、内部関数がコアで定義されているため、スクリプトまたはインクルードファイル内のコード行に内部関数が定義されていることを通知できないためです。$exception->getTrace();exception_handler

これは、エラー処理の操作の順序です。関数を呼び出した実際の行を取得する場合は、トレースを調べて、2番目の配列の行番号への参照を取得できます。

于 2012-07-20T17:31:45.687 に答える
1

良い質問!

ネイティブ関数とユーザー定義関数では、動作が異なるようです。ただし、PHPではなくCで記述されているため、ネイティブの場合、関数がどこで定義されているかを実際に知ることはできません。ただし、ユーザースペースコードの場合は、どこで呼び出されたかを確認すると便利です。1つの方法は、キャッチされた例外からのエラーメッセージを解析することです。これにより、作成されたファイルと行を取得できます。

function my_exception_handler($exception)
{
    $message = $exception->getMessage();
    $file    = $exception->getFile();
    $line    = $exception->getLine();

    if(strpos($message, 'called in') !== false) {
        preg_match('/called in .*php/', $message, $matches);
        $file = str_replace('called in ', '', $matches[0]);

        preg_match('/on line \d/', $message, $matches);
        $line = str_replace('on line ', '', $matches[0]);
    }

    echo 'line: ' . $line . PHP_EOL;
    echo 'file: ' . $file . PHP_EOL;
}

変更された質問からの出力ベースの描写my_exception_handler

line: 4
file: /tmp/file3.php
于 2012-07-20T17:24:24.900 に答える