phpのダイナミックエージェントと反射

5042 ワード

オブジェクト向けの高度な言語は、クラスの情報を動的に取得できる反射メカニズムを提供する必要があります.そうしないと、言語に柔軟性が欠け、多くのニーズが完了できません.phpの反射はiOSのランタイムメソッドに相当します.iOSの実行システムは、クラスの情報を動的に取得する一連のC言語方法を提供し、メッセージ転送を処理し、phpも同様の実装を提供し、iOSの使用よりも簡便であり、以下にいくつかの例を示す.
  • 関数の情報
  • を取得する.
            :'.$ref_fun->getFileName();
    //          
    echo '
    :'.$ref_fun->getStartLine(); // echo '
    :'.$ref_fun->getEndLine(); // echo '
    :'.$ref_fun->getDocComment(); // echo '
    :'.$ref_fun->getNumberOfParameters(); // echo '
    :';print_r($ref_fun->getParameters()); // -- echo '
    :'.$ref_fun->getReturnType(); // , , try catch try{ $ref_nfun = new ReflectionFunction('no_exist'); }catch (ReflectionException $e){ echo $e->getMessage(); }

    2.クラスの情報
    class Person{
    
        public $name,$age,$sex;
        static function show($name,$age,$sex=' '){
            echo "  :$name,  :$age,  :$sex";
        }
        function say($content){
            echo "     :$content";
        }
        function eat($food= 'apple'){
    
        }
    }
    $per = new Person();
    
    $ref = new ReflectionClass('Person');//       ,      
    //          
    $class_methods = $ref->getMethods();
    //     ,              
    echo '
    '; echo "
    ";print_r($class_methods);echo "
    ";
    //        
    $has_method = $ref->hasMethod('say');
    //         
    $some_method = new ReflectionMethod('Person','say');
    $some_method->isPrivate();//      ,  static,public
    //     ,
    if ($some_method->isPublic()&&!$some_method->isAbstract()) {
    
        if ($some_method->isStatic()){
            //          null,          ,          ,                 。
            /*
             * * The object to invoke the method on. For static methods, pass
             * null to this parameter.
             * 
             * @param mixed $parameter [optional] 

    * Zero or more parameters to be passed to the method. * It accepts a variable number of parameters which are passed to the method. *

    */ $some_method->invoke(null,'zhangsan','23'); } else { // $some_method->invoke($per,' '); } } }
  • エージェント
  • メッセージの は、 のクラス に され、iOSはdelegateによって されてもよいし、 に する で されてもよい.
    //  B show       A show  
    class A{
        function show(){
            echo "classA show  ";
        }
    }
    class B{
        private $obj;
        function __construct(){
            $this->obj = new A();
        }
        function __call($name, $arguments)
        {
             $ref = new ReflectionClass($this->obj);
             if ($ref->hasMethod($name)){
                 $method = $ref->getMethod($name);
                 if ($method->isPublic()&&!$method->isAbstract()&&count($arguments)){
                     if ($method->isStatic()){
                         $method->invoke(null);
                     }
                     else{
                         $method->invoke($this->obj);
                     }
                 }
             }
        }
    }
    
  • プラグインケース
  • include_once __DIR__."/plugin.php";
    function get_plugin_menus(){
        $menus = array();
        $all_class = get_declared_classes();//      
        foreach ($all_class as $cls){
            $ref_cls = new ReflectionClass($cls);
            if ($ref_cls->implementsInterface('Plugin')){//         
                if ($ref_cls->hasMethod('showMenu')){
                    $method = $ref_cls->getMethod("showMenu");
                    if ($method->isStatic()){
                        $method->invoke(null);
                    }
                    else{
    //                    $method->invoke(new $cls());//     
                        $instance = $ref_cls->newInstance();
                        $menu = $method->invoke($instance);
                    }
                }
            }
            $menus = array_merge($menus,$menu);
        }
        return $menus;
    }
    echo "
    ";get_plugin_menus();echo "
    ";
    
    interface Plugin{
        function showMenu();
    }
    class MyPlugin implements Plugin{
    
        function showMenu()
        {
            $menu = array(
                array(
                    'name' => 'menu1', 'link' => 'index.php?act=link1'
                ),
                array(
                    'name' => 'menu2', 'link' => 'index.php?act=link2'
                )
            );
            return $menu;
        }