php的反射使用
反射: 面向对象编程中对象被赋予了自省的能力,而这个自省的过程就是反射
反射,直观理解就是根据到达地找到出发和来源.比如, 你给我一个对象 我可以通过这个对象找到它所属的类,和属性方法
反射的使用:
<?php class person{ public $name; public $gender; public function say() { echo $this->name; } public function set($name, $value) { $this->$name = $value; } public function get($name) { return $this->$name; } } $p = new person(); //第一种方法进行反射------------------------------------------------- /* $p->name = "zhansan"; $p->gender = 'man'; $p->age = 21; $reflect = new ReflectionObject($p); //获取属性列表 $props = $reflect->getProperties(); foreach($props as $prop) { print $prop->getName().PHP_EOL; } //获取对象方法列表 $m = $reflect->getMethods(); foreach ($m as $prop) { print $prop->getName().PHP_EOL; } */ // 第二种方法进行反射------------------------------------------------ //返回对象属性的关联数组 // var_dump(get_object_vars($p)); //类属性 // var_dump(get_class_vars(get_class($p))); // var_dump(get_class_methods(get_class($p))); //使用反射------------------------------------ $obj = new ReflectionClass('person'); $className = $obj->getName(); $Methods = $Propeerties = array(); foreach($obj->getProperties() as $v) { $Propeerties[$v->getName()] = $v; } foreach($obj->getMethods() as $v) { $Methods[$v->getName()] = $v; } echo "class {$className}\n{\n"; is_array($Propeerties) && ksort($Propeerties); foreach($Propeerties 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 "\t function{$k}(){}\n"; } echo "} \n";
会输出:
class person { public gender; public name; functionget(){} functionsay(){} functionset(){} }
再来看一个例子
<?php class mysql { 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 ReflectionClass($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'); ?>
会输出:
方法前拦截记录log 连接数据库a 方法后拦截