문제

각 메소드 내에서 명시 적 호출을하지 않고 메소드 매개 변수, 항목 및 출구에서 콜백을 설정할 수있는 방법이 있습니까? 기본적 으로이 정보를 각 방법에 대해 수동으로 수행하지 않고도 로거 클래스 (정적)에 로그인하고 싶습니다.

지금 당장 나는 이것을 달성하기 위해 모든 방법에서 logger :: logentry () 및 logger :: logexit ()를 호출해야합니다. 나는 이것을 할 필요가 없다 :

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

        // Do some stuff...

        Logger::logExit();
    }
}
도움이 되었습니까?

해결책

래퍼 클래스를 사용하십시오. 이 방법에는 다음과 같은 이점이 있습니다.

  • 기본 클래스 구조 / 방법 서명을 변경할 필요가 없습니다.
  • 로깅 변경? 이 클래스를 업데이트하십시오
  • 객체 호출 업데이트 대 로그하려는 모든 클래스에 코드 삽입

.

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);

다른 팁

디버깅을 위해 기능 로깅을하고 싶다면 Xdebug 확장자를 살펴볼 수 있습니다. 런타임에서 기능 호출을 가로 채는 좋은 방법은 없으며 자동화 된 가로 채기는 훌륭한 런타임 오버 헤드를 추가합니다.

xdebug를 사용하면 대신 필요로하는 것만으로도 다른 것들을 얻을 수 있습니다.

(따라서 XDEBUG는 PHPUNIT와 함께 사용하여 단위 테스트 및 범위 분석을 수행합니다.)

__call의 문제

__call은 문제에 대한 재미있는 해결책이 될 수 있지만 3 이 문제, 즉 문제

  • 상당한 실행 오버 헤드. __call-> call_user_func_array를하고 있습니다. 말 그대로 하나를 추가하지는 않지만 모든 실행에 대한 기능 호출.

  • 배경 트레이스가 구분할 수 없게됩니다. 전화하려고했던 실제 기능은 __call 및 call_user_func_array의 바다에서 길을 잃어 버립니다.

  • 멍청한 숨겨진 기능 : _로 직접 호출하거나 보는 것을 막기 위해 _로 접두사의 "숨기기"로 돌아갑니다. 함수 이름의 이름을 want이면 __call로 돌아갑니다. 트리거는 원하지 않으므로 이미 끔찍한 기능 이름으로 가득 찬 전체 수업을 받았습니다. 개발자들은 다양한 장소에서 직접 전화를 받고 싶어합니다. (그리고 나중에 __call을 제거하려면 코드를 깨지 않도록 이러한 모든 기능을 바꿔야합니다!)

따라서 PHP 코드를 사용하여이를 구현하는 경우, Codebase의 미래의 사용자는 아니다 함께 일하고 싶습니다. 필요할 때 투명하게 추가 할 수있는 Xdebug와 같은 무언가를 얻는 것이 훨씬 더 좋습니다.

마법 기능을 사용할 수 있습니다 __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"
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top