PHP 反射 API 浅谈

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 类的某个方法的信息:

​ 比如:

  1. 获取方法的访问修饰符: public、 protected、 private、 static
  2. 获取方法的参数列表
  3. 获取方法形参个数
  4. 调用类的方法
// 获取 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

http://php.net/manual/en/book.reflection.php

https://hackoops.com/405.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡德咏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值