反射
反射,能够让我们清楚的知道类的常量、属性、方法、参数、注释等信息,从而利用其进行一系列的操作,例如利用反射实现注入控制反转。
下面是简单的反射代码,这里利用了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); }
我们日常的业务中对于代码的耦合性很注重,毕竟耦合度高就意味着代码难以维护,所以很多设计模式也是出于此考虑来设计的,包括框架也同样如此。
现在我们可以看看是如何做到解耦,尽量降低耦合度的呢。使用反射机制加上注入控制反转就能够实现了。
转发一篇博文,很不错,了解了原理就可以在具体的项目实现中用到了