反射

反射,能够让我们清楚的知道类的常量、属性、方法、参数、注释等信息,从而利用其进行一系列的操作,例如利用反射实现注入控制反转。

下面是简单的反射代码,这里利用了ReflectionClass反射类,和异常处理Exception类

<?php 
namespace Extend;

use ReflectionClass;//使用反射
use Exception;//使用异常处理

/**
 * 用户相关类
 * Class User
 * @package  Extend
 */
Class User{
    const ROLE = 'student';//定义常量
    public $username = '';//定义属性
    private $password = '';//定义属性
    protected $protected = '';//定义属性

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }

    /**
     * 获取用户名
     * @return  string
     */
    public function getUsername(){
        return $this->username;
    }

    /**
     * 设置用户名
     * @param  string $username
     */
    public function setUsername($username){
        $this->username = $username;
    }

    /**
     * 获取密码
     * @return string
     */
    public function getPassword(){
        return $this->password;
    }

    /**
     * 设置密码
     * @param  string $password
     */
    public function setPassword($password){
        $this->password = $password;
    }
}

//将类名User做为参数,即可建立User类的反射类
$class = new ReflectionClass('Extend\User');

//获取User类的所有属性,返回数组
echo '获取User类的所有属性,返回数组:<br>';
$properties = $class->getProperties();
var_dump($properties);

//获取User类的password属性
echo '获取User类的password属性:<br>';
$proprety = $class->getProperty('password');
var_dump($proprety);

//获取User类的所有方法,返回数组
echo '获取User类的所有方法,返回数组:<br>';
$methods = $class->getMethods();
var_dump($methods);

//获取User类的password方法
echo '获取User类的password方法:<br>';
$method = $class->getMethod('getPassword');
var_dump($method);

//获取所有常量,返回常量定义的数组
echo '获取所有常量,返回常量定义的数组:<br>';
$constants = $class->getConstants();
var_dump($constants);

//获取ROLE常量
echo '获取ROLE常量:<br>';
$constant  = $class->getConstant('ROLE');
var_dump($constant);

//获取类的命名空间
echo '获取类的命名空间:<br>';
$namespace = $class->getNamespaceName();
var_dump($namespace);

//获取User类的注释文档,即定义在类之前的注释
echo '获取User类的注释文档,即定义在类之前的注释:<br>';
$comment_class = $class->getDocComment();
var_dump($comment_class);

//获取User类中GetUsername方法的注释文档
echo '获取User类中GetUsername方法的注释文档:<br>';
$comment_method = $class->getMethod('getUsername')->getDocComment();
var_dump($comment_method);


echo '<br><br><br>交互:<br>';
//须实例化反射类,但是上面已经实例了,就不在实例化了
//创建User类的实例
$instance = $class->newInstance('youyou',1,'***');

//User类的实例调用,setUsername方法设置用户名
$instance->setUsername('youyou_2');
//用过User类的实例调用,getUsername方法获取用户名
$value = $instance->getUsername();
echo $value.'<br>';

//通过反射类设置指定实例username的属性值
$class->getProperty('username')->setValue($instance,'youyou_3');
//通过反射类获取指定username的属性值
$value = $class->getProperty('username')->getValue($instance);
echo $value.'<br>';

//通过反射类调用指定实例的方法,并请传送参数
$class->getMethod('setUsername')->invoke($instance,'youyou_4');
//通过反射类调用指定实例的方法
$value = $class->getMethod('getUsername')->invoke($instance);
echo $value.'<br>';

try{
    $property = $class->getProperty('password');
    //修改$property对象的可访问性
    $property->setAccessible(true);
    $property->setValue($instance,'password_2');
    $value = $property->getValue($instance);
    echo $value.'<br>';

}catch(Exception $e){
    throw new Exception($e);
}

我们日常的业务中对于代码的耦合性很注重,毕竟耦合度高就意味着代码难以维护,所以很多设计模式也是出于此考虑来设计的,包括框架也同样如此。

现在我们可以看看是如何做到解耦,尽量降低耦合度的呢。使用反射机制加上注入控制反转就能够实现了。

转发一篇博文,很不错,了解了原理就可以在具体的项目实现中用到了

 传送门

 

posted @ 2019-03-27 18:47  谦逊的铅笔  阅读(299)  评论(0编辑  收藏  举报