PHP具有完整的反射API,提供了对类、接口、函数、方法和扩展进行逆向工程的能力。通过类的反射提供的能力我们能够知道类是如何被定义的,它有什么属性、什么方法、方法都有哪些参数,类文件的路径是什么等很重要的信息。正是因为类的反射,很多PHP框架才能实现依赖注入自动解决类与类之间的依赖关系,这给我们平时的开发带来了很大的方便。
本文主要是讲解如何利用类的反射来实现依赖注入(Dependency Injection),并不会去逐条讲述PHP Reflection里的每一个API。为了更好地理解,我们通过一个例子来看类的反射,以及如何实现依赖注入。
下面这个类代表了坐标系里的一个点,有两个属性横坐标x和纵坐标y。
/** * Class Point */ class Point { public $x; public $y; /** * Point constructor. * @param int $x horizontal value of point's coordinate * @param int $y vertical value of point's coordinate */ public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; } }
接下来这个类代表圆形,可以看到在它的构造函数里有一个参数是Point类的,即Circle类是依赖与Point类的。
class Circle { /** * @var int */ public $radius;//半径 /** * @var Point */ public $center;//圆心点 const PI = 3.14; public function __construct(Point $point, $radius = 1) { $this->center = $point; $this->radius = $radius; } //打印圆点的坐标 public function printCenter() { printf('center coordinate is (%d, %d)', $this->center->x, $this->center->y); } //计算圆形的面积 public function area() { return 3.14 * pow($this->radius, 2); } }
ReflectionClass
下面我们通过反射来对Circle这个类进行反向工程。把Circle类的名字传递给reflectionClass来实例化一个ReflectionClass类的对象。
$reflectionClass = new reflectionClass(Circle::class); //返回值如下 object(ReflectionClass)#1 (1) { ["name"]=> string(6) "Circle" }
反射出类的常量
$reflectionClass->getConstants();
返回一个由常量名称和值构成的关联数组
array(1) { ["PI"]=> float(3.14) }
通过反射获取属性
$reflectionClass->getProperties();
返回一个由ReflectionProperty对象构成的数组
array(3) { [0]=> object(ReflectionMethod)#2 (2) { ["name"]=> string(11) "__construct" ["class"]=> string(6) "Circle" } [1]=> object(ReflectionMethod)#3 (2) { ["name"]=> string(11) "printCenter" ["class"]=> string(6) "Circle" } [2]=> object(ReflectionMethod)#4 (2) { ["name"]=> string(4) "area" ["class"]=> string(6) "Circle" } }
内容版权声明:除非注明,否则皆为本站原创文章。