更准备的说是 如何用PHP分析类内部的结构。
介绍
当我开始学习PHP编程时,可能并不知道 Reflection API
的强大功能,主要原因是我不需要它来设计我的类,模块甚至是包等等,但是它在很多地方都有非常不错的能力。
下面我们来介绍 Reflection API
,主要是从这几个方面
- 什么是Reflection API?
- 安装和配置
- 使用
- 总结
什么是 Reflection API
Reflection
是计算机程序在运行时检查,修改自己的结构和行为的能力 - 维基百科
这是什么意思呢?让我们来看下面的代码片段:
/**
* Class Profile
*/
class Profile
{
/**
* @return string
*/
public function getUserName(): string
{
return 'Foo';
}
}
现在,Profile类是一个使用 ReflectionClass
的黑盒子,你可以获取它里面的内容:
// instantiation
$reflectionClass = new ReflectionClass('Profile');
// get class name
var_dump($reflectionClass->getName());
=> output: string(7) "Profile"
// get class documentation
var_dump($reflectionClass->getDocComment());
=> output:
string(24) "/**
* Class Profile
*/"
因此,ReflectionClass
就像我们Profile类的分析师,这是 Reflection API
的主要思想。
除了上面用到的,其实还有更多,如下:
ReflectionClass:报告一个类的信息。 ReflectionFunction:报告有关函数的信息。 ReflectionParameter:检索有关函数或方法参数的信息。 ReflectionClassConstant:报告关于类常量的信息。
更多文档可以看这里 反射
安装和配置
Reflection API
是PHP内置的,不需要安装或配置,它已经是核心的一部分。
使用
在这里,我们通过更多,来看如何使用 Reflection API:
例一:获取特定类的父类
// here we have the child class
class Child extends Profile
{
}
$class = new ReflectionClass('Child');
// here we get the list of all parents
print_r($class->getParentClass()); // ['Profile']
例二:获取 getUserName()
函数注释
$method = new ReflectionMethod('Profile', 'getUserName');
var_dump($method->getDocComment());
=> output:
string(33) "/**
* @return string
*/"
例三:它可以像 instanceof
和 is_a()
一样来验证对象:
$class = new ReflectionClass('Profile');
$obj = new Profile();
var_dump($class->isInstance($obj)); // bool(true)
// same like
var_dump(is_a($obj, 'Profile')); // bool(true)
// same like
var_dump($obj instanceof Profile); // bool(true)
例子四:在某些情况下,你会发现自己停留在单元测试中,想知道如何测试私有函数?!
// add getName() scope as private
private function getName(): string
{
return 'Foo';
}
$method = new ReflectionMethod('Profile', 'getUserName');
// check if it is private so we set it as accessible
if ($method->isPrivate()) {
$method->setAccessible(true);
}
echo $method->invoke(new Profile()); // Foo
前面的例子非常简单,下面是一些可以广泛查找Reflection API的地方:
-
文档生成器:laravel-apidoc-generator软件包,它广泛使用
ReflectionClass
&ReflectionMethod
来获取关于类和方法的信息,然后处理它们,检出这个代码块。 -
依赖注入容器:下一篇来看。
结论
PHP提供了一个丰富的反射API,使我们可以更容易到达OOP结构的任何区域。
说白了就是在PHP运行时,可以通过反射深入到类的内部,做我们想做的事情。
关于更多PHP知识,可以前往 PHPCasts
来源:oschina
链接:https://my.oschina.net/u/172914/blog/1823136