php 反射 常用吗,学习猿地-详解 PHP 反射的基本使用

PHP 反射

今天我要给大家讲解的是 PHP 当中使用非常普遍的高级操作:反射。反射在当今几乎所有的 PHP 框架或者工具中都占用非常重要的角色,就比如 Laravel 的容器,容器对于 Laravel 架构来说极其重要,Laravel 的核心类 Illuminate\Foundation\Application 就是继承自 Illuminate\Container\Container 类。为了让大家彻底的理解反射,我这里写这篇博文,希望大家能够仔细阅读,我还写了一个简单的容器,这个容器,是我今天上午实现的,它也是基于反射实现的,代码量不大,但也不是那么容易理解,代码已经上传到了码云 php-base-container。

预备知识

大家可以参考 php 的官方地址,这里有对反射详细的论述,php 反射。

对于反射,我们会接触到四个类,分别是:

ReflectionClass

ReflectionFunction

ReflectionMethod

ReflectionParameter

为了让大家明白这个这四个类的作用,我给大家写了一个下面的例子。

class Printer

{

}

class Student

{

private $name;

private $year;

public function __construct($name, $year)

{

$this->name = $name;

$this->year = $year;

}

public function getValue()

{

return $this->name;

}

public function setBase(Printer $printer, $name, $year = 10)

{

$this->name = $name;

$this->year = $year;

}

}

上面我们声明了 2 个类 Printer 和 Student,测试如下:

$refl_class = new ReflectionClass(Student::class);

$object = $refl_class->newInstanceArgs(["obama", 100]);

echo get_class($object) . "\n";

echo $object->getValue();

控制台打印结果如下:

3cd16a8798cc75291e306eaa1ec163cf.png

首先打印的是 Student 这个类的类名,然后打印了 obama,我来解释下上面的代码, new ReflectionClass (Student::class) 创建了一个代表 Student 类的 ReflectionClass 对象,这个类的对象有一个方法 newInstanceArgs,这个方法可以创建 Student::class 类的对象,它的参数为 Student 类构造函数所需要的参数,我们的参数为 obama 和 100,紧接着调用 get_class 方法获取刚才创建对象的类,也就是我们打印的第一行 Student,印证了我们上面所说的。因为 $object 就是 Student 类的对象,所以我们可以调用 getValue 方法,返回值就是 name,结果为 obama。

上面我们分析了 ReflectionClass,下面我们再来分析下面的这个:

$refl_method = $refl_class->getMethod("setBase");

echo get_class($refl_method) . "\n";

$parameters = $refl_method->getParameters();

foreach ($parameters as $parameter) {

echo $parameter->getName() . "\n";

if ($parameter->getClass() != null) {

echo $parameter->getClass()->getName() . "\n";

}

if ($parameter->isDefaultValueAvailable()) {

echo $parameter->getDefaultValue() . "\n";

}

}

上面的代码运行结果如下

864f0c38e35ad5cc48e6662df0bb2987.png

之前我们创建了 ReflectionClass 类的对象为 $refl_class,这里我们调用它的方法 getMethod,这个 getMethod 会返回当前 Student 类的 setBase,但是它是一个 ReflectionMethod 类的实例,这里的 get_class ($refl_method) 就会打印出 $refl_method 的类为 ReflectionMethod,也就是控制台的第一行结果,ReflectionMethod 类有一个方法叫做 getParameters,这个方法会返回 ReflectionMethod 所对应方法(这里就是 setBase)的所有参数构成的数组,这个数组的每一个元素都是 ReflectionParameter 类的对象,接下来的 foreach 遍历所有的参数,首先检查 $parameter->getClass () 的返回值,ReflectionParameter 类的 getClass 方法返回的是这个参数所对应的类,也就是说 getClass 返回的是 ReflectionClass 类的对象,ReflectionClass 类的对象有一个 getName 方法,这个方法返回类的名字,ReflectionParameter 类还有一个比较常用的方法,就是 isDefaultValueAvailable,他检查这个参数是否有默认的值,如果这个参数有默认的值的话,那么 getDefaultValue 方法就可以获取到这个默认值。

上面分析了 ReflectionMethod 和 ReflectionParameter 两个类,还有一个要讲,如下:

function display($a, $b, Printer $printer)

{

echo "called" . "\n";

}

$refl_function = new ReflectionFunction("display");

$parameters = $refl_function->getParameters();

foreach ($parameters as $parameter) {

echo $parameter->getName() . "\n";

if ($parameter->getClass() != null) {

echo $parameter->getClass()->getName() . "\n";

}

if ($parameter->isDefaultValueAvailable()) {

echo $parameter->getDefaultValue() . "\n";

}

}

代码运行结果如下:

ddf8fb8f45bc19da07d1a4b869585e4a.png

上面的代码很简单,首先我定义了名为 display 的方法,它有三个参数,紧接着看,我们创建了一个 ReflectionFunction 类的对象,它的参数为函数名,也就是说 ReflectionFunction 是对函数的封装。

ReflectionFunction 类也有一个名为 getParameters 的方法,他返回的值和 ReflectionMethod 的 getParameters 方法的返回值是一样的,都是

ReflectionMethod 类的数组,接下来的 foreach 便利操作和上面讲解 ReflectionMethod 类的操作的时候是一模一样的,不再详述。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值