0

したがって、「ブリッジ」クラスと呼ばれるものを介して、他のクラスを「混合」するように設計されたクラスがあります。たとえば、サンプルクラスがあります。

class A{
    public function __construct(){}

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

class B{
    public function __construct(){}

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

A と B の両方から継承する必要がある C という単一のクラスがある場合もありますが、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()
        ));
    }
}

そして最後に、これらすべてを機能させる mix-in クラスができました。注:このコードは、pear 命名基準を使用してクラスをロードするオートローダーがあることを前提としています。

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 

これを見つけることができない特定の理由はありますか?クラスがロードされ、メソッドが配列に格納され、明らかにメソッドの配列でメソッドが見つかりました。メソッドは公開されています。どうしたの?

4

1 に答える 1

0

への呼び出しcall_user_funcはメソッド名だけを渡しているため、グローバル関数を探しています。クラス名またはインスタンスを渡す必要があります。

$a = new A();  // Or however you plan to get your instance of A
call_user_func(array($a, $method));
于 2013-10-08T19:07:35.760 に答える