1

各メソッド内で明示的な呼び出しを行わずに、メソッドのパラメーター、エントリ、および終了にコールバックを設定する (または自動的にログに記録する) 方法はありますか? 基本的に、メソッドごとに手動で行う必要なく、この情報をロガー クラス (静的) に記録したいと考えています。

現在、これを実現するには、すべてのメソッドで Logger::logEntry() と Logger::logExit() を呼び出す必要があります。これを行う必要がないようにしたい:

class TestClass {
    public function tester($arg) {
        Logger::logEntry();
        Logger::info('Parameter $arg => ' . $arg);

        // Do some stuff...

        Logger::logExit();
    }
}
4

3 に答える 3

11

ラッパー クラスを使用します。この方法には次の利点があります。

  • 基礎となるクラス構造/メソッド シグネチャを変更する必要はありません
  • ロギングを変更しますか? このクラスを更新するだけです
  • オブジェクト呼び出しの更新と、ログに記録するすべてのクラスへのコードの挿入

.

class LogWatch {
    function __construct($class)    {
        $this->obj  =   $class;
    }

    function __call($method, $args) {
        if (in_array($method, get_class_methods($this->obj) ) ) {
            Logger::logEntry();
            Logger::info('Parameter '.implode(', ', $args) );

            call_user_func_array(array($this->obj, $method), $args);

            Logger::logExit();

        } else {
            throw new BadMethodCallException();
        }
    }
}

$test = new LogWatch(new TestClass() );
$test->tester();

// you can use instances of `LogWatch()` just like your watched class
// including passing appropriate params:
$test->tester($param1, $param2);
于 2008-11-14T01:18:54.580 に答える
5

デバッグのために関数のログを記録したい場合は、Xdebug 拡張機能を調べることをお勧めします。実行時に関数呼び出しをインターセプトする良い方法はありません。また、自動インターセプトは実行時の大きなオーバーヘッドを追加します。

XDebug を使用すると、代わりに必要に応じて有効にしたり、他の多くのものを取得したりできます

(したがって、XDebug を PHPUnit と共に使用して、単体テストとカバレッジ分析を行います。)

__call の問題

__call は問題の楽しい解決策に見えるかもしれませんが、これには3 つの問題があります。

  • かなりの実行オーバーヘッド。__call --> call_user_func_arrayを実行すると、実行ごとに文字通り 1 つではなく2 つの関数呼び出しが追加されます。

  • バックトレースが判読不能になる: 呼び出そうとした実際の関数が __call と call_user_func_array の海で失われ、バックトレースが非常に困難になります。特に、バックトレースに引数リストが含まれている場合はそうです。

  • 愚かな隠し関数: PHP4 スタイルの関数の「非表示」に戻ります。関数の前に _ を付けて、ユーザーが関数を直接呼び出したり、表示したりしないようにします。トリガーしないので、クラス全体が本当に恐ろしい関数名でいっぱいになり、開発者はとにかくさまざまな場所で直接呼び出したくなるでしょう。(そして、後で __call を取り除きたい場合は、コードを壊さないように、これらすべての関数の名前を変更する必要があります!)

したがって、これを実装するために php コードを利用している場合、コードベースの将来のユーザーが作業したくないような恐ろしいコードになります。必要なときに透過的に追加できるもの ( Xdebug など) を取得する方がはるかに優れており、コードの汚染を大幅に節約できます。

于 2008-11-14T01:16:23.680 に答える
-1

あなたは魔法の機能を使うことができます__call。その名前に一致する関数がない場合に呼び出されます。メソッドの名前を変更して、接頭辞 (例: アンダースコア) を付け、オプションでそれらを非公開/保護に設定します。

class TestClass {
    public function __call($function, $args) {
        Logger::logEntry();
        Logger::info('Parameters: ' . implode(", ", $args);

        $localFunc = "_" . $function;
        $return = $this->$localFunc($args);

        Logger::logExit();

        return $return;
    }

    private function _tester() {
        // do stuff...
        return "tester called";
    }
}

 $t = new TestClass();
 echo $t->tester();
 // "tester called"
于 2008-11-14T00:33:44.920 に答える