标签:
面向对象编辑中对象被赋予了自省的能力,而这个自省的过程就是反射.
class HandsonBoy
{
public $name = ‘chenqionghe‘;
public $age = 18;
public function __set($name,$value)
{
echo ‘您正在设置私有属性‘.$name.‘<br >值为‘.$value.‘<br>‘;
$this->$name = $value;
}
public function __get($name)
{
if(!isset($this->$name))
{
echo ‘未设置‘.$name;
$this->$name = "正在为你设置默认值".‘<br>‘;
}
return $this->$name;
}
}
$boy = new HandsonBoy();
echo $boy->name.‘<br />‘;
$boy->hair = ‘short‘;
$reflect = new ReflectionObject($boy);
$props = $reflect->getProperties();
//获取属性的名字
foreach($props as $prop)
{
print $prop->getName().PHP_EOL;
}
//获取对象方法列表
$methos = $reflect->getMethods();
foreach($methos as $method)
{
print $method->getName().PHP_EOL;
}
也可以不用反射API,使用class函数,返回对象属性的关联数组以及更多的信息:(针对于公开的属性和):
//返回对象属性的关联数组 var_dump(get_object_vars($boy)); //类属性 var_dump(get_class_vars(get_class($boy))); //返回由类的属性的方法名组成的数组 var_dump(get_class_methods(get_class($boy)));
反射API的功能显然更强大,甚至能还原这个类的原型,包括方法的访问权限,以下简单封装了一个打印类的代码
/**
* @param $classObject 对象或者类名
*/
function getClass($classObject)
{
$object = new ReflectionClass($classObject);
$className = $object->getName();
$Methods = $Properties = array();
foreach($object->getProperties() as $v)
{
$Properties[$v->getName()] = $v;
}
foreach($object->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更是有几十个,可以说,反射完整地描述了一个类或者对象的原型.反射不仅可以用于类和对象,还可以用于函数,扩展模块,异常等.
<?php
class mysql
{
function connect($db)
{
echo "连接到数据库{$db[0]}".PHP_EOL;
}
}
class sqlproxy
{
private $target;
public function __construct($tar)
{
$this->target[] = new $tar;
}
public 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".PHP_EOL;
$method->invoke($obj,$args);
echo "方法后拦截".PHP_EOL;
}
}
}
}
}
$obj = new sqlproxy(‘mysql‘);
$obj->connect(‘chenqionghe‘);
标签:
原文地址:http://www.cnblogs.com/chenqionghe/p/4735753.html