2013-10-08 73 views
0

所以我有一個類,它被設計用來「混合」其他類,通過我稱之爲「橋」類。所以,你有你的樣品類,例如:Mixins,call_to_user_func找不到函數

class A{ 
    public function __construct(){} 

    public function hello_a(){ echo "hello A"; } 
} 

class B{ 
    public function __construct(){} 

    public function hello_b(){ echo "hello B"; } 
} 

您還可能有一個名爲C單類 - 這需要從A和B都繼承,但由於PHP不具有多重繼承,我們有以下幾點:

class C extends Bridge{ 
    public function __construct(){ 
     parent::__construct(); 
    } 

    public function hello_C(){ 
     $this->hello_a(); // Freaks out* 
    } 
} 

class Bridge extends AisisCore_Loader_Mixins{ 
    public function construct(){ 
     parent::construct(); 

     $this->setup(array(
      'A' => array(), 
      'B' => array() 
     )); 
    } 
} 

現在終於有了我們的混合類,它允許所有這些工作。 注意:這段代碼假設你有一個使用梨命名標準的自動加載器來爲你加載類。

class AisisCore_Loader_Mixins { 

    private $_classes; 

    private $_class_objects = array(); 

    private $_methods = array(); 

    public function __construct(){ 
     $this->init(); 
    } 

    public function init(){} 

    public function setup($class){ 
     if(!is_array($class)){ 
      throw new AisisCore_Loader_LoaderException('Object passed in must be of type $class_name=>$params.'); 
     } 

     $this->_classes = $class; 
     $this->get_class_objects(); 
     $this->get_methods();  
    } 

    public function get_class_objects(){ 
     foreach($this->_classes as $class_name=>$params){ 
      $object = new ReflectionClass($class_name); 
      $this->_class_objects[] = $object->newInstanceArgs($params); 
     } 
    } 

    public function get_methods(){ 

     foreach($this->_class_objects as $class_object){ 
      $this->_methods[] = get_class_methods($class_object); 
     } 

     return $this->_methods; 
    } 

    public function __call($name, $param = null){ 
     foreach($this->_methods as $key=>$methods){ 
      foreach($methods as $method){ 
       if($name === $method){ 
        return $this->isParam($method, $param); 
       } 
      } 
     } 

     throw new AisisCore_Loader_LoaderException("Method: " .$name. 
          " does not exist or it's access is not public"); 
    } 

    private function isParam($method, $param){ 
     if($param != null){ 
      call_user_func($method, $param); 
     }else{ 
      call_user_func($method); 
     }   
    } 
} 

可以在C類怎麼看上面的類時,我們只是簡單地叫hello_a。一切都很好了這一點,直到它試圖call_user_func()和怪胎說:

Warning: call_user_func() expects parameter 1 to be a valid callback, function 'hello_a' not found or invalid function name 

有它無法發現這是一個特別的原因?類被加載,方法被存儲在數組中,它顯然在方法數組中找到該方法,該方法是公共的。這是怎麼回事?

+0

'call_user_func(陣列($此,$法),$ PARAM);'或'call_user_func(陣列($此,$法));'? (或者你的類的實例如果不是$ this? –

回答

0

您致電call_user_func只傳遞方法名稱,所以它正在尋找一個全局函數。你必須通過你的類名或實例:

$a = new A(); // Or however you plan to get your instance of A 
call_user_func(array($a, $method));