2013-10-08 55 views
0

所以這是我的混合類:我的混合類引起我的班,成爲靜態 - PHP

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); 
      $object_name = get_class($object); 
      $this->_class_objects[$object->name] = $object->newInstanceArgs($params); 
     } 
    } 

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

     return $this->_methods; 
    } 

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

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

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

很簡單的東西,裝載一組類,允許您調用它們的功能等等,但我們有一個新問題。看來傳入這個的類被實例化爲靜態的,因此他們的方法不能使用$this->他們使用self::這是錯誤的。

讓我們看到的這一切是如何工作的例子:

class BaseBridge extends AisisCore_Loader_Mixins{ 

    public function __construct(){ 
     parent::construct(); 

     $this->setup(array('ClassB' => array())); 
    } 
} 

允許定義ClassB

class ClassB{ 

    public function __construct(){} 

    public function some_method(){ 
     $this->_some_private_method(); 
    } 

    private function _some_private_method(){} 
} 

非常基本的東西,所以讓勾了這一切在ClassA

class ClassA extends BaseBridge{ 

    public function __construct(){ 
     parent::__construct(); 
     $this->some_method(); 
    } 
} 

快速評論:我們有一個核心課程ClassA,它延伸了BaseBridge,這是我們在ClassA延伸的一個或多個(意圖用於更多)課程之間的橋接課程。在這種情況下,爲了簡單起見,僅從ClassB延伸。

這是什麼問題?看到,如何在ClassB,在做:$this->_some_private_method();雅即將歷史性和災難性失敗。 爲什麼?,因爲我得到錯誤:Using $this when not in object context這讓我很困惑,所以我將它改爲:self::$_some_private_method();,它的作用就像一個魅力。

爲什麼?以及我需要更改或修復哪些內容才能使$this可以在通過mixin類實例化的類中使用?

+4

有許多語言不支持多繼承的原因,你應該停止嘗試迫使PHP做一些它並不意味着做的事情... –

+0

標記爲不具有建設性。 @MarcB事情可能並不容易,但我設法得到這麼多。 – LogicLooking

+1

我的第一個建議是完全避免mixins/traits。 *通常*如果答案是多重繼承或橫向代碼重用,那麼您會問錯誤的問題。我的第二個建議是,如果你絕對必須這樣做......停止嘗試自己實現混合。只需升級到PHP5.4並使用[traits](http://php.net/manual/en/language.oop5.traits.php)作爲該語言的一部分。 – rdlowrey

回答

0

因此,通過一些細微的修改,我設法完成了這項工作。我怎麼都不相信有多個參數的函數會起作用 - 反饋意見。

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->name] = $object->newInstanceArgs($params); 
     } 
    } 

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

     return $this->_methods; 
    } 

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

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

    private function _is_param($class_name, $method, $param){ 
     if($param != null){ 
      $this->_param_is_array($class_name, $method, $param); 
     }else{ 
      call_user_func(array($this->_class_objects[$class_name], $method)); 
     }   
    } 

    private function _param_is_array($class_name, $method, $param){ 
     if(is_array($param)){ 
      call_user_func_array(array($this->_class_objects[$class_name], $method), $param); 
     }else{ 
      call_user_func(array($this->_class_objects[$class_name], $method, $param)); 
     }   
    } 
} 

現在在由該類註冊的類內部的函數可以使用$this->

問題是我不確定多個基於param的函數是否真的有效。