乐趣区

关于php:反射

什么是反射

反射是操纵面向对象范型中元模型的 API,可用于构建简单,可扩大的利用。

反射的作用

反射次要目标就是在运行时剖析类或者对象的状态,导出或提取出对于类、办法、属性、参数等的详细信息,包含正文

反射的利用

反射在日常的 Web 开发中其实用的不多,更多的是在偏差底层一些的代码中,比如说框架的底层中依赖注入、对象池、动静代理、主动获取插件列表、主动生成文档以及一些设计模式等等,都会大量使用到反射技术。

罕用的反射类

因为在日常开发中用的不是很多,所以目前就只学一些比拟罕用的反射类,等当前再深刻学习其余的内容。

比拟罕用的反射类:

  • ReflectionClass:报告了一个类的无关信息;
  • ReflectionFunction:报告无关办法的信息;
  • ReflectionMethod:报告无关函数的信息;
  • ReflectionParameter:检索函数或办法参数的相干信息。

例子

<?php

class Student
{
    public $name;
    public $year;
    public function __construct($name, $year)
    {
        $this->name = $name;
        $this->year = $year;
    }

    public function setBase(Printer $printer, $name, $year)
    {
        $this->name = $name;
        $this->year = $year;
    }

    public function getValue()
    {return $this->name;}
}

class Printer
{}

测试 ReflectionClass 类:

$reflClass = new ReflectionClass('Student');
echo get_calss($reflClass);
$s = $reflClass->newInstanceArgs(['程心', 18]);
echo $s->getValue();

输入如下:

[Running] php "d:\phpstudy_pro\WWW\Reflection\Foo.php"
ReflectionClass
程心
[Done] exited with code=0 in 1.198 seconds

这里须要留神的是:newInstanceArgs 办法模仿手动实例化对象,然而该办法的 参数是一个数组。

测试 ReflectionClass 类和 ReflectionParameter 类:

$reflClass = new ReflectionClass('Student');

$reflMethod = $reflClass->getMethod('setBase');
echo get_class($reflMethod) . PHP_EOL;

$params = $reflMethod->getParameters();
var_dump($params);

foreach ($params as $param) {echo $param->getName() . PHP_EOL;
    if ($param->getType() != NULL) {echo $param->getType()->getName() . PHP_EOL;}
    if ($param->isDefaultValueAvailable()) {echo $param->getDefaultValue() . PHP_EOL;
    }
    echo '--------' . PHP_EOL;  
} 

输入如下:

[Running] php "d:\phpstudy_pro\WWW\Reflection\Foo.php"
ReflectionMethod
array(3) {[0]=>
  object(ReflectionParameter)#3 (1) {["name"]=>
    string(7) "printer"
  }
  [1]=>
  object(ReflectionParameter)#4 (1) {["name"]=>
    string(4) "name"
  }
  [2]=>
  object(ReflectionParameter)#5 (1) {["name"]=>
    string(4) "year"
  }
}
printer
Printer
--------
name
--------
year
10
--------

[Done] exited with code=0 in 0.274 seconds

咱们调用反射类的 getMethod 办法,参数为 Student 类中 setBase 办法的办法名 setBase

该办法返回一个 ReflectionMethod 类,正如控制台中的第一行的输入。

ReflectionMethod 类有一个办法叫做 getParameters,该办法会返回 ReflectionMethod 所对应办法的所有参数形成的数组,这个数组的每一个元素都是 ReflectionParameter 类的对象。

接下来的 foreach 遍历所有的参数,首先查看 $parameter->getType() 的返回值。

如果一个指定了参数类型,ReflectionParameter 类的 getType 办法 就返回 ReflectionType 对象,否则返回 null

Returns a ReflectionType object if a parameter type is specified, null otherwise.

ReflectionType 类报告无关函数的参数 / 返回类型以及类的属性类型的信息,并且提供了 getName 办法来获取参数类型的名称。

ReflectionParameter 类还有一个比拟罕用的办法——isDefaultValueAvailable,用于查看这个参数是否有默认值。如果这个参数有默认的值,就能够用 getDefaultValue 办法来获取这个默认值。

用于测试 ReflectionFunction 类:

function display($a, $b, Printer $printer)
{echo "called" . "\n";}

$reflFunction = new ReflectionFunction("display");
echo get_class($reflFunction) . PHP_EOL;

$params = $reflFunction->getParameters();
var_dump($params);

foreach ($params as $param) {echo $param->getName() . PHP_EOL;

    if ($param->getType() != null) {echo $param->getType()->getName() . PHP_EOL;}
    if ($param->isDefaultValueAvailable()) {echo $param->getDefaultValue() . PHP_EOL;
    }
    echo '--------'. PHP_EOL;
}

输入如下:

[Running] php "d:\phpstudy_pro\WWW\Reflection\Foo.php"
ReflectionFunction
array(3) {[0]=>
  object(ReflectionParameter)#2 (1) {["name"]=>
    string(1) "a"
  }
  [1]=>
  object(ReflectionParameter)#3 (1) {["name"]=>
    string(1) "b"
  }
  [2]=>
  object(ReflectionParameter)#4 (1) {["name"]=>
    string(7) "printer"
  }
}
a
--------
b
--------
printer
Printer
--------

[Done] exited with code=0 in 0.247 seconds

ReflectionMethod 反射类一样,ReflectionFunction 提供了 getParameters 办法来获取函数的参数。

参考资料

  1. 详解 PHP 反射的根本应用
  2. 反射在 PHP 中的利用
  3. 手册
退出移动版