php使用反射API

来源:互联网 发布:淘宝店铺和旺铺的区别 编辑:程序博客网 时间:2024/06/05 05:51

反射是一种对象编程中赋予对象的一种自省能力。通过反射api,我们可以可以找到对象所属类的属性、方法以及它们的访问权限,他是一种动态获取信息以及动态调用对象方法的功能。

在这里,我们假设已经定义了一个person类,而student是这个类的实例化对象,现在要获取这个student对象的方法和属性列表。

(1)通过反射

//获取对象属性列表$reflect = new ReflectionObject($student);$props = $reflect->getProperties();foreach($props as $prop) {     print $prop->getName()."\n";}//获取对象方法列表$m = $reflect->getMethods();foreach ($m as $prop) {    print $prop->getName()."\n";}

(2)使用class函数,返回对象属性的关联数组以及更多的信息

//返回对象属性的关联数组var_dump(get_object_vars($student));//类属性var_dump(get_class_vars(get_class($student)));//返回由类组成的方法数组var_dump(get_class_methods(get_class($student)));*get_class()方法可以知道页面传递对象的所属类。

反射Api的功能更加强大,甚至可以还原这个类的原型,包括方法的访问权限。

//反射获取类的原型$obj = new ReflectionObject($student);$className = $obj->getName();$methods = $properties = array();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";

反射的作用:使用反射原理实现动态代理

class Mysql{      public function connect($db)      {            echo "连接到数据库${db[0]}\r\n";      }}class SqlProxy{      private $target;      function __construct ($tar) {            $this->target = new $tar();      }      function __call ($name,$args) {            foreach ($this->target as $obj) {                  $r = new ReflectionObject($obj);                  if($method = $r->getMethod($name)) {                        if($method->isPublic()&&!$method->isAbstract()) {                              echo "方法前拦截记录LOG\r\n";                              $method->invoke($obj,$args);                              echo "方法后拦截\r\n";                        }                  }            }      }}$obj = new SqlProxy('Mysql');$obj->connect('member');

在上面的代码中,真正的操作类是mysql类,但是sqlporxy类实现了根据动态传入参数,代替实际的类运行,并且在方法运行前后进行拦截,并且动态的改变类中的属性和方法,这就是简单的动态代理。

很多时候,善用反射能够实现代码的优雅和简洁,但是反射会破坏类的封装性,因为反射使本不应该暴露的属性或方法被强制暴露,因此,它在实际开发中不常用。

0 0
原创粉丝点击