php 反射原理,PHP反射机制

PHP 自 5.0 版本以后添加了反射机制,其中包含了一套强大的反射 API,允许在 PHP 运行环境中,访问或使用类、方法、属性、参数和注释等,其功能十分强大,经常用于高扩展的 PHP 框架、自动加载插件、自动生成文档,甚至可以用来扩展 PHP 语言。

因为反射机制是 PHP 內建的 OOP 扩展,为语言本身自带的特性,所以不需要额外添加扩展或者配置就可以使用。反射 API 会基于类、方法、属性、参数等维护相应的反射类,已提供相应的调用 API。如下表所示:

类型

说明

Reflector

Reflector 是一个接口,被所有可导出的反射类所实现(implement)

Reflection

反射(reflection)类

ReflectionClass

报告了一个类的有关信息

ReflectionZendExtension

报告Zend扩展的相关信息

ReflectionExtension

报告了PHP扩展的有关信息

ReflectionFunction

报告了一个函数的有关信息

ReflectionFunctionAbstract

ReflectionFunction 的父类

ReflectionMethod

报告了一个方法的有关信息

ReflectionObject

报告了一个对象(object)的相关信息

ReflectionParameter

取回了函数或方法参数的相关信息

ReflectionProperty

报告了类的属性的相关信息

如何使用反射

假设我们定义了一个 Websit 类,示例代码如下所示:

namespace Site;

/**

* Website 类

*/

class Website{

public $name;

private $url;

const TITLE = 'C语言中文网';

public function __construct($name, $url){

$this->name = $name;

$this->url = $url;

}

public function getName(){

return $this->name;

}

/**

* 获取连接

* @return [type] [description]

*/

private function getUrl(){

return $this->url;

}

}

?>

想要获取 Websit 类中的属性或者方法,首先需要建立这个类的反射类实例,通过反射类的实例即可获取类中的属性或方法。不管类中定义的成员权限声明是否为 public,都可以获取到。示例代码如下所示:

$class = new \ReflectionClass('Site\\Website'); // 以类名 Website 作为参数,即可创建 Website 类的反射类

$properties = $class->getProperties(); // 以数组的形式返回 Website 类的所有属性

$property = $class->getProperty('name'); // 获取 Website 类的 name 属性

$methods = $class->getMethods(); // 以数组的形式返回 Website 类的所有方法

$method = $class->getMethod('getName'); // 获取 Website 类的 getName 方法

$constants = $class->getConstants(); // 以数组的形式获取所有常量

$constant = $class->getConstant('TITLE'); // 获取 TITLE 常量

$namespace = $class->getNamespaceName(); // 获取类的命名空间

$comment_class = $class->getDocComment(); // 获取 Website 类的注释文档,即定义在类之前的注释

$comment_method = $class->getMethod('getUrl')->getDocComment(); // 获取 Website 类中 getUrl 方法的注释文档

?>

运行上面的代码即可获取 Website 类的相应信息,这里就不再一一打印出来了,大家可以自行尝试打印。

另外,不仅可以通过反射类访问类的方法和属性,还可以创建原来类的实例或者直接调用类里面的方法。示例代码如下所示:

$class = new \ReflectionClass('Site\\Website'); // 创建 Website 类的反射类

$instance = $class->newInstance('C语言中文网', 'http://c.biancheng.net/php/'); // 创建 Website 类的实例

$instance->getName(); // 调用 Website 类的 getName 方法

$class->getProperty('name')->setValue($instance, 'C语言'); // 通过反射类设置 name 的属性值

$value = $class->getProperty('name')->getValue($instance); // 通过反射类获取 name 的属性值

$value = $class->getMethod('getUrl')->invoke($instance); // 通过反射类调用指定实例的方法,还可传入响应参数,如面下一行所示

// $value = $class->getMethod('getUrl')->invoke($instance, 'C语言中文网'); // 通过反射类调用指定实例的方法, 并传入参数

?>

需要注意的是,在平常开发中,用到反射的地方并不多,主要是对对象进行调试,或者用来获取类的信息。在 MVC 和插件开发中,使用反射很常见,但是反射的消耗也很大,所有在可以找到替代方案的情况下,尽量不用反射。关于反射类更详细的介绍大家可以参考 https://www.php.net/manual/zh/book.reflection.php。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值