什么是反射
反射是操纵面向对象范型中元模型的 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
方法来获取函数的参数。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。