2009-10-08 4 views
9

내 상황에 가장 코드의 비트와 함께 설명되어 있습니다 클래스,하지만 내 목적을 위해, 좋은 경우 __call 함수를 그들을 처리 할 수 ​​있습니다. 그냥 물건을 더 깔끔하고 관리하기 쉽게 만듭니다.PHP의 마술 방법 __call

PHP로 가능합니까?

답변

13

__call()은 함수가 발견되지 않을 때만 호출되므로 작성한 예제는 불가능합니다.

2

이 직접 할 수없는, 그러나 이것은 하나 개의 가능한 대안이다 :

class SubFoo { // does not extend 
    function __construct() { 
     $this->__foo = new Foo; // sub-object instead 
    } 
    function __call($func, $args) { 
     echo "intercepted $func()!\n"; 
     call_user_func_array(array($this->__foo, $func), $args); 
    } 
} 

것은 이런 종류의 디버깅 및 테스트를위한 좋은,하지만 당신은 가능한 한 많은 __call()과 친구를 피하려고 생산 코드는 매우 효율적이지 않습니다.

+0

. Facade 패턴을 따라야합니다. 이 모든 함수를 재정의하려는 객체를 "소유"하는 래퍼 클래스를 가져야합니다. 필요에 따라 메서드를 전달하려면 __call()을 사용하고 적절한 추가 작업을 수행하십시오. 코드가 끊임없이 호출되고 앱이 CPU 제한 (거의 예외)하지 않는 한 성능을 떨어 뜨리지 마십시오. 이러한 종류의 트레이드 오프를 결정할 때 프로그래머 시간은 성능보다 거의 항상 중요합니다. –

0

부모 바()에 추가 할 필요가있는 경우이 작업을 수행 할 수 있습니까?

class SubFoo extends Foo { 
    function bar() { 
     // Do something else first 
     parent::bar(); 
    } 
} 

호기심에 관한 질문입니까? 동일한 효과를 가지고 무엇을 할 수 있는지

+1

이 문제는 부모 클래스가 함수 힙을 가질 수 있다는 사실에서 비롯된 것이며, 하위 클래스에서 모두 동일한 동작을 적용하기를 원하지 않습니다. '부분) 모두 – nickf

+0

@nickf 당연히, 이것은 내가 PHP에없는 이유를 이해할 필요가있는 것처럼 보인다. –

0

는 다음과 같습니다 : 당신이 시도 할 수

<?php 

class hooked{ 

    public $value; 

    function __construct(){ 
     $this->value = "your function"; 
    } 

    // Only called when function does not exist. 
    function __call($name, $arguments){ 

     $reroute = array(
      "rerouted" => "hooked_function" 
     ); 

     // Set the prefix to whatever you like available in function names. 
     $prefix = "_"; 

     // Remove the prefix and check wether the function exists. 
     $function_name = substr($name, strlen($prefix)); 

     if(method_exists($this, $function_name)){ 

      // Handle prefix methods. 
      call_user_func_array(array($this, $function_name), $arguments); 

     }elseif(array_key_exists($name, $reroute)){ 

      if(method_exists($this, $reroute[$name])){ 

       call_user_func_array(array($this, $reroute[$name]), $arguments); 

      }else{ 
       throw new Exception("Function <strong>{$reroute[$name]}</strong> does not exist.\n"); 
      } 

     }else{ 
      throw new Exception("Function <strong>$name</strong> does not exist.\n"); 
     } 

    } 

    function hooked_function($one = "", $two = ""){ 

     echo "{$this->value} $one $two"; 

    } 

} 

$hooked = new hooked(); 

$hooked->_hooked_function("is", "hooked. "); 
// Echo's: "your function is hooked." 
$hooked->rerouted("is", "rerouted."); 
// Echo's: "our function is rerouted." 

?> 
1

한 가지는 개인 또는 보호로 기능 범위를 설정하는 것입니다. 클래스 외부에서 하나의 private 함수가 호출되면 __call 매직 메소드가 호출되며이를 이용하여 악용 할 수 있습니다.

관련 문제