PHP的Reflection反射机制的深入分析

内容摘要
这篇文章主要为大家详细介绍了PHP的Reflection反射机制的深入分析,具有一定的参考价值,可以用来参考一下。
文章正文

这篇文章主要为大家详细介绍了PHP的Reflection反射机制的深入分析,具有一定的参考价值,可以用来参考一下。

PHP5添加了一项新的功能:Reflection。这个功能使得程序员可以reverse-engineer class, interface,function,method and extension。通过PHP代码,就可以得到某object的所有信息,并且可以和它交互。假设有一个类Person:

代码如下:

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
<code>
class Person { 
 
 /**
 
     * For the sake of demonstration, we"re setting this private
 
     */
 
    private $_allowDynamicAttributes = false;
 
  
 
    /** type=primary_autoincrement */
 
    protected $id = 0;
 
  
 
    /** type=varchar length=255 null */
 
    protected $name;
 
  
 
    /** type=text null */
 
    protected $biography;
 
  
 
        public function getId()
 
        {
 
         return $this->id;
 
        }
 
        public function setId($v)
 
        {
 
            $this->id = $v;
 
        }
 
        public function getName()
 
        {
 
         return $this->name;
 
        }
 
        public function setName($v)
 
        {
 
          $this->name = $v;
 
        }
 
        public function getBiography()
 
        {
 
           return $this->biography;
 
        }
 
        public function setBiography($v)
 
        {
 
          $this->biography = $v;
 
        }
 
}
 
</code>

 

通过ReflectionClass,我们可以得到Person类的以下信息:1.常量 Contants2.属性 Property Names3.方法 Method Names4.静态属性 Static Properties5.命名空间 Namespace6.Person类是否为final或者abstract

只要把类名"Person"传递给ReflectionClass就可以了:

 

代码如下:

1
2
3
4
<code>
$class = new ReflectionClass('Person');
 
</code>

 

获取属性(Properties):

 

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<code>
$properties = $class->getProperties();
 
foreach($properties as $property) {
 
    echo $property->getName()."\n";
 
}
 
// 输出:
 
// _allowDynamicAttributes
 
// id
 
// name
 
// biography
 
</code>

 

默认情况下,ReflectionClass会获取到所有的属性,private 和 protected的也可以。如果只想获取到private属性,就要额外传个参数:

代码如下:

1
2
3
4
<code>
$private_properties = $class->getProperties(ReflectionProperty::IS_PRIVATE);
 
</code>

 

可用参数列表:

代码如下:

1
2
3
4
5
6
7
8
<code>
ReflectionProperty::IS_STATIC
 
ReflectionProperty::IS_PUBLIC
 
ReflectionProperty::IS_PROTECTED
 
ReflectionProperty::IS_PRIVATE</code>

 

如果要同时获取public 和private 属性,就这样写:ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED应该不会感觉陌生吧。

通过$property->getName()可以得到属性名,通过getDocComment可以得到写给property的注释。

 

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<code>
foreach($properties as $property) {
 
    if($property->isProtected()) {
 
        $docblock = $property->getDocComment();
 
        preg_match('/ type\=([a-z_]*) /', $property->getDocComment(), $matches);
 
        echo $matches[1]."\n";
 
    }
 
}
 
// Output:
 
// primary_autoincrement
 
// varchar
 
// text
 
</code>

 

有点不可思议了吧。竟然连注释都可以取到。获取方法(methods):通过getMethods() 来获取到类的所有methods。返回的是ReflectionMethod对象的数组。不再演示。最后通过ReflectionMethod来调用类里面的method。

 

代码如下:

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
<code>
$data = array("id" => 1, "name" => "Chris", "biography" => "I am am a PHP developer");
 
foreach($data as $key => $value) {
 
    if(!$class->hasProperty($key)) {
 
        throw new Exception($key." is not a valid property");
 
    }
 
  
 
    if(!$class->hasMethod("get".ucfirst($key))) {
 
        throw new Exception($key." is missing a getter");
 
    }
 
  
 
    if(!$class->hasMethod("set".ucfirst($key))) {
 
        throw new Exception($key." is missing a setter");
 
    }
 
  
 
    // Make a new object to interact with
 
    $object = new Person();
 
  
 
    // Get the getter method and invoke it with the value in our data array
 
    $setter = $class->getMethod("set".ucfirst($key));
 
    $ok = $setter->invoke($object, $value);
 
  
 
    // Get the setter method and invoke it
 
    $setter = $class->getMethod("get".ucfirst($key));
 
    $objValue = $setter->invoke($object);
 
  
 
    // Now compare
 
    if($value == $objValue) {
 
        echo "Getter or Setter has modified the data.\n";
 
    } else {
 
        echo "Getter and Setter does not modify the data.\n";
 
   }
 
}
 
</code>

 

有点意思吧。

注:关于PHP的Reflection反射机制的深入分析的内容就先介绍到这里,更多相关文章的可以留意

代码注释

作者:喵哥笔记

IDC笔记

学的不仅是技术,更是梦想!