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
方法后拦截

 

posted @ 2017-03-16 15:03  ー個亽の江湖  阅读(98)  评论(0编辑  收藏  举报