php 反射API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php
 
class Person{
    public $name;
    function __construct($name){
        $this->name = $name;
    }
}
 
interface Module{
    function execute();
}
 
class FtpModule implements Module{
    private $host;
    private $user
 
    function setHost($host){
        $this->host = $host;
        echo "FtpModule::setHost() : {$this->host} <br/>";
    }
 
    function setUser($user){
        $this->user = $user;
        echo "FtpModule::setUser() : {$this->user} <br/>";
    }
 
    function execute(){
        //执行一些操作
        echo "Host: {$this->host} & User: {$this->user} <br/>";
    }
}
 
class PersonModule implements Module{
    private $name;
 
    function setPerson( Person $person ){
        $this->name = $person->name;
        echo "PersonModule::setPerson() :  {$person->name} <br/>";
    }
 
    function execute(){
        //执行一些操作
        echo "Name: {$this->name}<br />";
    }
}
 
class ModuleRunner{
    private $configData array(
            "PersonModule" => array('person'=>'leokim'),
            "FtpModule" => array('host'=>'www.leokim.cn','user'=>'leokim')
        );
 
    private $modules array();
 
    function init(){
        $interface new ReflectionClass('Module');
 
        foreach($this->configData as $modulename => $params){
            $module_class new ReflectionClass($modulename);
 
            if( !$module_class->isSubclassOf($interface)){
                throw new Exception("unknow module type:$modulename");
            }
            $module $module_class->newInstance();
 
            foreach($module_class->getMethods() as $method){
                //module,module内的方法,方法的参数
                $this->handleMethod($module$method$params);
            }
            array_push($this->modules, $module);
        }
    }
 
    //handleMethod()检验并调用Module对象的setter方法
    function handleMethod(Module $module, ReflectionMethod $method$params){
        $name $method->getName();
        //所需要的参数
        $args $method->getParameters();
         
        if(count($args) != 1 || substr($name, 0, 3) != "set"){
            return false;
        }
 
        $property strtolower(substr($name, 3));
        if(!isset($params[$property])){
            return false;
        }
 
        print_r($args[0]);
        echo ' | ';
 
        //ReflectionMethod::invoke()。它以一个对象和任意数目的方法作为参数
        //可以通过两种途径调用invoke()方法:
        //1.如果setter方法不需要对象参数,可以用用户提供的属性字符串来调用ReflectionMethod::invoke()。
        //2.如果方法需要对象作为参数,可以使用属性字符串来实例化正确类型的对象,然后传递给setter。
        //这个例子里 Person是有Class的 所以在else里执行,Ftp并没有Class所以在if里执行
        $arg_class $args[0]->getClass();
 
        if(empty($arg_class)){
            $method->invoke($module$params[$property]);
        }else{
            $method->invoke($module$arg_class->newInstance($params[$property]));
        }
 
        //执行固有的function execure()
        $module->execute();
 
    }
}
 
 
//在ModuleRunner::init()方法运行时,ModuleRunner对象存储着许多Module对象,而所有Module对象都包含着数据。
//ModuleRunner类现在可以用一个类方法来循环遍历没个Module对象,并逐一调用各Module对象中的excute()方法
$test new ModuleRunner();
$test->init();
 
?>