2

カスタム クラスでエラーを「スロー」するために trigger_error を使用しています。私の問題は、trigger_error が、trigger_error が呼び出された行番号を出力することです。たとえば、次のコードがあるとします。

01    <?php
02        class Test {
03            function doAction() {
04                $this->doSubAction();
05            }
06            
07            function doSubAction() {
08                if(true)
09                    trigger_error('Custom error', E_USER_WARNING);
10            }
11        }
12        
13        $var = new Test();
14        $var->doAction();
15    ?>

PHP は次のように出力します。

警告: 9行目のtest.phpのカスタム エラー

次のように、doAction() 関数が呼び出された行 (クラスの外部で呼び出されたメソッドであり、内部で行われたすべての呼び出しを無視します) を PHP に返させるにはどうすればよいでしょうか?

警告: test.phpの14行目のカスタム エラー

編集:私の例を、私が達成しようとしているものに少し近づけるように変更しました。

4

5 に答える 5

2

The best thing to do is set up an error handler that shows a full stack trace.

Set up a custom error handler, and call debug_print_backtrace() in it. You will find this useful in general, as well in this specific circumstance.

于 2008-10-09T03:08:37.960 に答える
1

さて、私の最終的な解決策に興味がある方のために、テスト可能なすべてのケースで正しい行番号を返す次のコードをフレームワークに統合しました。私たちはそれを生産に使用しています。

ErrorHandlerクラス

キャッチされていない PHP 例外、PHP エラー、およびPEAR::Errors をキャッチします。コードにフレームワーク固有の機能が含まれている場合は、少し変更する必要がありますが、追跡するのは難しくありません。楽しみ!

于 2009-07-17T19:59:16.607 に答える
0

私は通常、trigger_error()もそこに置きます。これにより、呼び出された場所と実際のエラーが発生した場所を正確に知ることができます。次に、本番環境ですべてのエラーを電子メールで送信します。これは自動ではないことは知っていますが、少なくとも何が起こったのかを追跡することはできます。

于 2008-10-09T04:19:03.840 に答える
0

2 つの選択肢がありますが、どちらも特に口に合うものではありません。

  • オーバーライド test()__LINE__に引数を指定させます (例: " test(__LINE__)"、そして引数を trigger_error に渡します)。カスタム エラー メッセージを出力するエラー ハンドラを設定します。注:これは恐ろしく醜いです。:-)

  • エラー ハンドラを設定し、debug_backtrace() の恐ろしく大きな出力を呼び出して処理します。この関数はデバッグ時に役立ちます...しかし、あなたがやろうとしていることにはやり過ぎです。システムの通常の運用の一部としてこの機能を使用しないでください。

簡単な答え: 難しすぎます。試してはいけません。:-|

于 2008-10-09T03:20:44.800 に答える
0

私は自分の 2 セントをポットに投入し、他の開発者がよく使用する、私が構築する PHP ライブラリに対して、そのまま、または小さなカスタマイズを加えて、一般的に使用するものについて話し合うことにしました。

プログラムの実行中に発生する可能性のあるエラーを 2 つのカテゴリに分類します。誤ったプログラミングの結果であるエラーと、ユーザー エラーまたは何らかの外部要因によって発生するエラーです。前者については、trigger_error を E_USER_ERROR と組み合わせて使用​​し、後者は例外、具体的にはライブラリ内の他のすべての例外によって継承されるパッケージ例外を使用します。

開発エラーの例としては、文字列であると予想されるパラメーターに整数を渡すこと (V7 より前)、または存在しないクラスのメソッドまたはプロパティにアクセスすることが挙げられます。(ここで開発者の想像力を働かせることができます。)明らかに、別の開発者はエラーが __get または __set ステートメントまたはその他の魔法の構造の奥深くで生成されたことを気にしませんが、むしろ知りたいと思うでしょう。特に彼らの間違いはどこですか。それに直面しましょう...開発者はバックトレースを通り抜けるのが好きではありません。

したがって、エラー メッセージをローカライズするために使用する方法は次のとおりです。

function localize_error_msg($msg, $level) {
    $level = (int)$level;
    $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, $level + 1)[$level];
    return $msg . " in " . $backtrace['file'] . " on line " . $backtrace['line'];
}

使用されるコンストラクトに依存するバックトレース レベルを渡します。これは一般に 1 または 2 であり、残りは自明です。

「in file on line n」の繰り返しシーケンスを防ぐために、次のエラー ハンドラを追加します。

set_error_handler(function($errno, $errstr, $errfile, $errline) {
    if (preg_match('/on line \d+$/', $errstr) === 1)
        die($errstr);
    else return false;
}, E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE);

繰り返しますが、私はそれをシンプルに保つのが好きです。エラーメッセージのローカリゼーションはハンドラーで行われるべきであると主張することができますが、その場合、深さを渡すことができる必要があります。これは、ハンドラー内のさらに 2 レベルの深さであり、まあ、後で面倒になります。それ。

ハッピートレイル!

于 2016-02-10T00:45:39.913 に答える