PHP反射API是什么?
本文以 demo 演示的方式讲解 PHP 反射 API 的简单应用。
PHP5之后提供了反射API的功能,它提供了对类、接口、函数和方法以及扩展的反向工程的能力。另外,还可以利用反射API获取类、方法、函数的注释。
// Person 类
class Person {
/**
* For the sake of demonstration, we're setting this private
*/
private $_allowDynamicAttributes = false;
/**
* type=primary_autoincrement
*/
protected $id = 0;
/**
* type=varchar length=255 null
*/
protected $name;
/**
* type=text null
*/
protected $biography;
public function getId() {
return $this->id;
}
public function setId($v) {
$this->id = $v;
}
public function getName() {
return $this->name;
}
public function setName($v) {
$this->name = $v;
}
public function getBiograpy() {
return $this->biography;
}
public function setBiography($v) {
$this->biography = $v;
}
public function getAddress($province, $city) {
return $city .', ' . $province;
}
}
一、通过 ReflectionClass,我们可以得到 Person 类的以下信息:
1、常量 constants
2、属性 Property Names
3、方法 Method Names
4、命名空间 Namespace
5、Person 类是否为 final 、abstract
6、Person 类是否有某个方法
$class = new ReflectionClass('Person'); // 建立 Person 类的反射
$instance = $class->newInstance(); // 获得 Person 类的实例
1) 获取属性
$class = new ReflectionClass('Person');
$instance = $class->newInstance();
$properties = $class->getProperties();
foreach($properties as $property)
{
echo $property->getName() . "<br />"; // 使用的 web 换行符,如果使用命令行测试,请根据自己的操作系统的换行符做对应的修改
}
以上代码的输出结果为:
_allowDynamicAttributes
id
name
biography
默认情况下, ReflectionClass 会获取所有的属性, private 和 protected 的都可以。如果只想获取 private 属性,就要额外传个参数:
// 代码参考:
$private_properties = $class->getProperties(ReflectionPropery::IS_PRIVATE);
可用的参数如下:
ReflectionProperty::IS_STATIC
ReflectionProperty::IS_PUBLIC
ReflectionProperty::IS_PROTECTED
ReflectionProperty::IS_PRIVATE
2) 获取注释:
通过 getDocComment 可以得到对应属性的注释
$class = new ReflectionClass('Person');
$instance = $class->newInstance();
$properties = $class->getProperties();
foreach ($properties as $property) {
if ($property->isProtected()) {
$docblock = $property->getDocComment();
preg_match('/type\=([a-z_]*)/', $property->getDocComment(), $matches);
echo $matches[1] . "\n";
}
}
3)获取类的方法
用法如下:
getMethod()
hasMethod(string)
getMethod(string)
4) 执行类的方法
$class = new ReflectionClass('Person');
$instance = $class->newInstance(); // 获取 Person 的实例
$n = $instance->setName('zhangsan'); // 调用实例 setName 方法
$n = $instance->getName();
var_dump($n);
// 获取 setName 方法,调用并传递参数
$method = $class->getmethod('setName');
$method->invokeArgs($instance, array('Leon'));
$method = $class->getmethod('getName');
echo $method->invoke($instance);
二、通过 ReflectionMethod, 我们可以得到 Person 类的某个方法的信息:
比如:
- 获取方法的访问修饰符: public、 protected、 private、 static
- 获取方法的参数列表
- 获取方法形参个数
- 调用类的方法
// 获取 Person 类的 getAddress 方法
$method = new ReflectionMethod('Person', 'getAddress');
// 判断该方法是否是 public,并且是非静态方法
if($method->isPublic() && !$method->isStatic())
{
echo 'Action is right.<br />';
}
// 获取方法的形参个数
echo $method->getNumberOfParameters();
echo '<pre>';
// 获取方法的形参
var_dump($method->getParameters());
思考题:
反射 API 究竟有什么用呢 ?
参考:
https://www.cnblogs.com/KeenLeung/p/6041280.html