PHP反射基础知识回顾

PHP反射基础知识回顾

反射是编程语言的高级特性,能在运行时让代码有感知代码的能力。PHP自5起支持反射机制,其是各种OOP框架底层实现的重要支撑。

反射

从一个简单的例子理解反射:人有五官四肢,但鲜有人清楚人体内部的经脉走向、骨骼构造。如果你修仙顺利PHP反射基础知识回顾,在丹田深处练出元婴,那么就通过元婴透析身体内部的构造。理解内部构造后,还可以让元婴指引体内真气在经脉的流向,早日修成正果。

如其名,反射是(从镜子里)照出自身。我们写代码,告诉代码怎么运行,事件发生在编译期。代码运行期间,代码如何知道自己的结构以及能力呢?反射机制相当于代码的元婴,使代码能够感知自身结构,并可(部分)改变运行行为。

与运行时类型信息( Type , RTTI)不同php 反射,反射重点在运行时检测、感知、改变自身的结构和行为。反射是元编程()的重要组成部分。

PHP反射API

反射不是语法分析,不操作表达式、代码语句。反射获取的是代码的结构,即函数、类这些构件的结构。PHP中的反射API均以开头(接口除外),重点在函数和类两种结构。而函数可以看成类的成员函数(多一个隐式的this参数)或者静态成员函数(类型),所以了解反射API可从类信息的开始。

提供了以下获取类基本信息的接口:

:获取成员变量/属性,返回一个数组;类中有对属性详细说明的API:是否默认属性(),是否私有属性()等。同时还提供获取特定类别属性的API:,;:获取类中定义的常量;:获取类中定义的方法,返回一个数组;将在下文讲解;:获取类实现的接口;:获取父类的实例。

在反射中,类、接口、特性不分家php 反射,所以提供类型判定API:、。

除了以上基本信息,(包括/)还提供了一些不可思议的能力:

:获取类的文档注释信息;:获取类定义的文件;: 获取类定义的起始行号;: 获取类定义的结束行号;:获取类定义的修饰符,其意义名字可通过::得到,例如:,final。

如果说前述的类结构信息可以通过现有的API获取(/等),上面列出的功能基本上只能通过反射API获取(PHP文件中定义的类并且知道定义文件,可以利用得到相同结果,但是实现非常复杂)。这些行为发生在运行期间。由此可见反射API在分析类结构信息功能上的强大。

除了,和是另外反射中另外两个重要的类。函数()定义在类外部,方法()定义在类内部,两者其实同源,在反射API中有共同的父类:。有两者的大部分API,并且基本上是最重要的API。其中最值得关注的是其参数信息的API:。其获取函数的参数信息,返回一个数组。结合和php 反射,函数(方法)的结构基本上就清晰了。

API操作

知道人体构造和体内真气分布,你可以引导真气到手指,练成一阳指、六脉神剑、弹指神通、九阴白骨爪等;也可以让真气汇聚,冲破任督二脉,开辟洞天;还可以逆转全身经脉,练成蛤蟆功…内省的好处可见一斑。

反射让代码感知自身结构,有什么好处呢?反射API提供了三种在运行时对代码操作的能力:

设置访问控制权:。可获取私有的方法/属性。注意:只是让方法/成员变量可以//,并不代表类定义的访问存取权限改变;调用函数/方法:/。配合获取函数参数的API,可以安全的传参和调用函数,()的增强版;不依赖构造函数生成实例:。

以单例来说一下反射API的功能,单例类代码如下:

# foo.php
class Foo {
 private static $id;
 private static $instance;
 private function __construct() {
 ++ self::$id;
 fwrite(STDOUT, "construct, instance id: " . self::$id . "n");
 }
 public static function getSingleton() {
 if (self::$instance === null) {
 self::$instance = new self();
 }
 return self::$instance;
 }
}

在Foo类中,构造函数是私有PHP反射基础知识回顾,获取实例只能通过方法,并且获取到的是单例。但在反射API加持下,能获取多个实例:

$instance1 = Foo::getSingleton();
var_dump($instance1);
$class = new ReflectionClass("Foo");
$constructor = $class->getConstructor();
if ((ReflectionProperty::IS_PUBLIC & $constructor->getModifiers()) === 0) {
 $constructor->setAccessible(true);
}
$instance2 = $class->newInstanceWithoutConstructor();
$constructor->invoke($instance2);
var_dump($instance2);
# 脚本执行结果
construct, instance id: 1
object(Foo)#1 (0) {
}
construct, instance id: 2
object(Foo)#4 (0) {
}

我们成功的生成了两个实例,并调用构造函数完成对象初始化。如果没有反射API,这几乎是不可能完成的工作。

除了这三种操作,反射API几乎已无在运行时动态改变代码的行为。但作为动态语言,PHP内置了将数据转换成代码执行的能力(例如/eval、动态函数名调用)。而PHP的好基友则可以随时在运行时改变任意函数的行为:

php 反射

PHP作为最好的语言,理应能做到在运行时动态增减/改变函数定义。这就需要用到另一个PHP核心开发者“ ”打造的大杀器:拓展。这部分内容不属于反射,加之本人了解不深,不再详述。

对比

整理一下反射API和函数式API在功能上的差异:

功能函数式API反射API

函数是否存在

类是否存在

方法是否存在

变量/属性是否存在

获取类变量

::

获取类方法

::

获取类常量

::ant(s)

获取函数/方法参数信息

/::

获取函数/方法返回值

/::

类使用的特性

::

获取父类

::

获取类实现的接口

::

获取类所在名字空间

::

函数调用

()

()::(Args)

获取类名

/::class

::

获取函数名

/

/::

php 反射

获取类/常量/变量/方法修饰符

///::

获取所在文件

///::

获取所在行(范围)

//::/

获取文档

//::

ion

拓展

从上表可以看出反射API较函数式API能提供更全面的信息。还需要注意到这类魔术常量是编译期的工作,不是运行时的能力。

同时给出RTTI的函数式API和反射API在功能上的差异:

php 反射

功能函数式API反射API

类型判断

//等

获取对象的类名

::

获取对象父类

::

类型/继承检测

/is_a/

::/

生成器

总结

本文对PHP中的反射机制做了简要总结,并与在运行时获取代码信息的函数式API做了对比。即使你用得再熟练,等文本操作用得再顺手,反射API仍有其独到一面,值得了解。如本人之前博文“PHP中的重载”所言,有了反射,/、这些函数应该可以退休。但是考虑到兼容、使用便利、运行效率等因素,许多框架仍然依赖这些API。

感谢阅读,欢迎指正!

公告:
1. 本站所有资源来源于用户上传和网络,如有侵权请联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系站长处理!
6. 本站不售卖代码,资源标价只是站长收集整理的辛苦费!如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
7. 站长QQ号码 2205675299

资源库 - 资源分享下载网 » PHP反射基础知识回顾

常见问题FAQ

关于资源售价和售后服务的说明?
本站所有资源的标价均为本站收集资源的辛苦费,不代表资源本身的价值。软件是高智慧高价值的商品,不可能是白菜价。本站资源标价只是赞助费用,收取的赞助费仅用来维持本站的日常运营!毕竟收集整理资料需要投入云计算资源和站长大量的精力。
代码有没有售后服务和技术支持?
由于代码的运行具有不可预见性,本站不保证代码完整可运行,不提供技术支持和售后服务。 本站原创代码都是站长自己开发的,可以有偿提供技术支持服务。 网站里标明【亲测】的代码都是站长亲测过的,其他的代码由于精力有限,没有一一测试,不能保证代码就一定能够使用,更没有技术支持服务,下载前请自行斟酌。
有没有搭建服务?
由于搭建服务比较费时费力,所以本站除了原创代码外均不提供搭建服务。本站分享代码纯属兴趣爱好,不以盈利为目的,请勿咨询有没有搭建服务,谢谢理解。
链接地址失效了怎么办?
请带上资源链接地址联系客服,工作时间内我们看到后将第一时间回复。
关于解压密码
本站资源一般都没有加密,如果发现需要解压密码的,那么就输入 hao.35dc.com 试试。

发表评论

资源库,由老程序员细心甄别、精心筛选,只为提供优质的源码资源

关于我们 联系我们