以下面的代码为例子,来直观的认识反射的使用。
<?php class Person { public $name; public $gender; public function say() { echo $this->name,"\tis",$this->gender,"\r\n"; } public function __set($name, $value) { echo "Setting $name to $value \r\n"; $this->$name = $value; } public function __get($name) { if(!isset($this->$name)) { echo '未设置'; $this->$name = "正在为你设置默认值"; } return $this->$name; } } $student = new person(); $student->name = 'Tom'; $student->gender = 'male'; $student->age = 24; 现在,要获取这个student对象的方法和属性列表该怎么做呢?代码如下所示: $student = new person(); $student->name = 'Tom'; $student->gender = 'male'; $student->age = 24; $reflect = new ReflectionObject($student); $props = $reflect->getProperties(); foreach($props as $prop) { print $prop->getName(). "\n"; } $m = $reflect->geMethods(); foreach ($m as $prop) { print $prop->getName(). "\n"; } 也可以不用反射API,使用class函数,返回对象属性的关联数组以及更多的信息: //返回对象属性的关联数组 var_dump(get_object_vars($student)); //类属性 var_dump(get_class_vars(get_class($student))); //返回由类的方法名组成的数组 var_dump(get_class_methods(get_class($student))); 假如这个对象是从其他页面传送过来的,怎么知道它属于哪个类呢?一句代码就可以搞定: //获取对象属性列表所属的类 echo get_class($student); 反射API的功能显然更强大,甚至还能还原这个类的原型,包括方法的访问权限,代码如下所示: <?php $obj = new ReflectionClass('person'); $className = $obj->getName(); $methods = $properties = []; foreach ($obj->getProperties() as $v) { $properties[$v->getName()] = $v; } foreach ($obj->getMethods() as $v) { $methods[$v->getName()] = $v; } echo "class {$className}\n{\n"; is_array($properties)&&ksort($properties); //短路语法 foreach ($properties as $k => $v) { echo "\t"; echo $v->isPublic() ? 'public' : '',$v->isPrivate() ? 'private' : '', $v->isprotected() ? 'protected' : '', $v->isStatic() ? 'static' : ''; echo "\t{$k}\n"; } echo "\n"; if(is_array($methods))ksort($methods); foreach ($methods as $k => $v) { echo "\tfunction {$k} () {}\n"; } echo "}\n"; 输出如下:
不仅如此,PHP手册中关于反射API更是有几十个,可以说,反射完整的描述了一个类或者对象的原型。反射不仅可以用于类和对象,还可以用于函数、扩展模块、异常等。