什么是反射
反射是操纵面向对象范型中元模型的 API,可用于构建简单,可扩大的利用。
反射的作用
反射次要目标就是在运行时剖析类或者对象的状态,导出或提取出对于类、办法、属性、参数等的详细信息,包含正文。
反射的利用
反射在日常的 Web
开发中其实用的不多,更多的是在偏差底层一些的代码中,比如说框架的底层中依赖注入、对象池、动静代理、主动获取插件列表、主动生成文档以及一些设计模式等等,都会大量使用到反射技术。
罕用的反射类
因为在日常开发中用的不是很多,所以目前就只学一些比拟罕用的反射类,等当前再深刻学习其余的内容。
比拟罕用的反射类:
ReflectionClass
:报告了一个类的无关信息;ReflectionFunction
:报告无关办法的信息;ReflectionMethod
:报告无关函数的信息;ReflectionParameter
:检索函数或办法参数的相干信息。
例子
<?phpclass 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"ReflectionMethodarray(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" }}printerPrinter--------name--------year10--------[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"ReflectionFunctionarray(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--------printerPrinter--------[Done] exited with code=0 in 0.247 seconds
与 ReflectionMethod
反射类一样,ReflectionFunction
提供了 getParameters
办法来获取函数的参数。
参考资料
- 详解 PHP 反射的根本应用
- 反射在 PHP 中的利用
- 手册