热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP反射API的功能和用途详解

本文详细介绍了PHP反射API的功能和用途,包括动态获取信息和调用对象方法的功能,以及自动加载插件、生成文档、扩充PHP语言等用途。通过反射API,可以获取类的元数据,创建类的实例,调用方法,传递参数,动态调用类的静态方法等。PHP反射API是一种内建的OOP技术扩展,通过使用Reflection、ReflectionClass和ReflectionMethod等类,可以帮助我们分析其他类、接口、方法、属性和扩展。

认识php反射API

它是指在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类、方法、属性、参数等的详细信息,包括注释。这种动态获取的信息以及动态调用对象的方法的功能称为反射API。反射是操纵面向对象泛型中元模型的API,其功能十分强大,可帮助我们构建复杂,可扩展的应用。

其用途如:自动加载插件,自动生成文档,甚至可用来扩充PHP语言。

php反射api由若干类组成,可帮助我们用来访问程序的元数据或者同相关的注释交互。借助反射我们可以获取诸如类实现了哪些方法,创建一个类的实例(不同于用new创建),调用一个方法(也不同于常规调用),传递参数,动态调用类的静态方法。

反射api是php内建的oop技术扩展,包括一些类,异常和接口,综合使用他们可用来帮助我们分析其它类,接口,方法,属性,方法和扩展。这些oop扩展被称为反射。

e3d774809dcbe3501b02f07e6afa5935.png

php反射API类

类描 述Reflection为类的摘要信息提供静态函数export()ReflectionClass类信息和工具ReflectionMethod类方法信息和工具ReflectionParameter方法参数信息ReflectionProperty类属性信息ReflectionFunction函数信息和工具ReflectionExtensionPHP扩展信息ReflectionException错误类

使用反射API这些类,我们可以获得在运行时访问对象、函数和脚本中的扩展的信息。通过这些信息我们可以用来分析类或者构建框架。

获取类的信息

我们在工作中使用过一些用于检查类属性的函数,例如:get_class_methods、getProduct等。这些方法对获取详细类信息有很大的局限性。

我们可以通过反射API类:Reflection 和 ReflectionClass 提供的静态方法 export 来获取类的相关信息, export 可以提供类的几乎所有的信息,包括属性和方法的访问控制状态、每个方法需要的参数以及每个方法在脚本文档中的位置。这两个工具类, export 静态方法输出结果是一致的,只是使用方式不同。

ReflectionClass类提供了非常多的工具方法,官方手册给的列表如下:

ReflectionClass::__construct — 初始化 ReflectionClass 类

ReflectionClass::export — 导出一个类

ReflectionClass::getConstant — 获取定义过的一个常量

ReflectionClass::getConstants — 获取一组常量

ReflectionClass::getConstructor — 获取类的构造函数

ReflectionClass::getDefaultProperties — 获取默认属性

ReflectionClass::getDocComment — 获取文档注释

ReflectionClass::getEndLine — 获取最后一行的行数

ReflectionClass::getExtension — 根据已定义的类获取所在扩展的 ReflectionExtension 对象

ReflectionClass::getExtensionName — 获取定义的类所在的扩展的名称

ReflectionClass::getFileName — 获取定义类的文件名

ReflectionClass::getInterfaceNames — 获取接口(interface)名称

ReflectionClass::getInterfaces — 获取接口

ReflectionClass::getMethod — 获取一个类方法的 ReflectionMethod。

ReflectionClass::getMethods — 获取方法的数组

ReflectionClass::getModifiers — 获取类的修饰符

ReflectionClass::getName — 获取类名

ReflectionClass::getNamespaceName — 获取命名空间的名称

ReflectionClass::getParentClass — 获取父类

ReflectionClass::getProperties — 获取一组属性

ReflectionClass::getProperty — 获取类的一个属性的 ReflectionProperty

ReflectionClass::getReflectionConstant — Gets a ReflectionClassConstant for a class's constant

ReflectionClass::getReflectionConstants — Gets class constants

ReflectionClass::getShortName — 获取短名

ReflectionClass::getStartLine — 获取起始行号

ReflectionClass::getStaticProperties — 获取静态(static)属性

ReflectionClass::getStaticPropertyValue — 获取静态(static)属性的值

ReflectionClass::getTraitAliases — 返回 trait 别名的一个数组

ReflectionClass::getTraitNames — 返回这个类所使用 traits 的名称的数组

ReflectionClass::getTraits — 返回这个类所使用的 traits 数组

ReflectionClass::hasConstant — 检查常量是否已经定义

ReflectionClass::hasMethod — 检查方法是否已定义

ReflectionClass::hasProperty — 检查属性是否已定义

ReflectionClass::implementsInterface — 接口的实现

ReflectionClass::inNamespace — 检查是否位于命名空间中

ReflectionClass::isAbstract — 检查类是否是抽象类(abstract)

ReflectionClass::isAnonymous — 检查类是否是匿名类

ReflectionClass::isCloneable — 返回了一个类是否可复制

ReflectionClass::isFinal — 检查类是否声明为 final

ReflectionClass::isInstance — 检查类的实例

ReflectionClass::isInstantiable — 检查类是否可实例化

ReflectionClass::isInterface — 检查类是否是一个接口(interface)

ReflectionClass::isInternal — 检查类是否由扩展或核心在内部定义

ReflectionClass::isIterateable — 检查是否可迭代(iterateable)

ReflectionClass::isSubclassOf — 检查是否为一个子类

ReflectionClass::isTrait — 返回了是否为一个 trait

ReflectionClass::isUserDefined — 检查是否由用户定义的

ReflectionClass::newInstance — 从指定的参数创建一个新的类实例

ReflectionClass::newInstanceArgs — 从给出的参数创建一个新的类实例。

ReflectionClass::newInstanceWithoutConstructor — 创建一个新的类实例而不调用它的构造函数

ReflectionClass::setStaticPropertyValue — 设置静态属性的值

ReflectionClass::__toString — 返回 ReflectionClass 对象字符串的表示形式。

除了获取类的相关信息,还可以获取 ReflectionClass 对象提供自定义类所在的文件名及文件中类的起始和终止行等相关源代码信息。

function getClassSource(ReflectionClass $class) {

$path = $class->getFileName(); // 获取类文件的绝对路径

$lines = @file($path); // 获得由文件中所有行组成的数组

$from = $class->getStartLine(); // 提供类的起始行

$to = $class->getEndLine(); // 提供类的终止行

$len = $to - $from + 1;

return implode(array_slice($lines, $from - 1, $len));

}

检查方法

类似于检查类,ReflectionMethod 对象可以用于检查类中的方法。

获得 ReflectionMethod 对象的方法有两种:

第一种是通过 ReflectionClass::getMethods() 获得 ReflectionMethod 对象的数组,这种方式的好处是不用提前知道方法名,会返回类中所有方法的 ReflectionMethod 对象。

第二种是直接使用 ReflectionMethod 类实例化对象,这种方式只能获取一个类方法对象,需要提前知道方法名。

ReflectionMethod 对象的工具方法:

ReflectionMethod::__construct — ReflectionMethod 的构造函数

ReflectionMethod::export — 输出一个回调方法

ReflectionMethod::getClosure — 返回一个动态建立的方法调用接口,译者注:可以使用这个返回值直接调用非公开方法。

ReflectionMethod::getDeclaringClass — 获取反射函数调用参数的类表达

ReflectionMethod::getModifiers — 获取方法的修饰符

ReflectionMethod::getPrototype — 返回方法原型 (如果存在)

ReflectionMethod::invoke — Invoke

ReflectionMethod::invokeArgs — 带参数执行

ReflectionMethod::isAbstract — 判断方法是否是抽象方法

ReflectionMethod::isConstructor — 判断方法是否是构造方法

ReflectionMethod::isDestructor — 判断方法是否是析构方法

ReflectionMethod::isFinal — 判断方法是否定义 final

ReflectionMethod::isPrivate — 判断方法是否是私有方法

ReflectionMethod::isProtected — 判断方法是否是保护方法 (protected)

ReflectionMethod::isPublic — 判断方法是否是公开方法

ReflectionMethod::isStatic — 判断方法是否是静态方法

ReflectionMethod::setAccessible — 设置方法是否访问

ReflectionMethod::__toString — 返回反射方法对象的字符串表达

在PHP5中,如果被检查的方法只返回对象(即使对象是通过引用赋值或传递的),那么 ReflectionMethod::retursReference() 不会返回 true。只有当被检测的方法已经被明确声明返回引用(在方法名前面有&符号)时,ReflectionMethod::returnsReference() 才返回 true。

检查方法参数

类似于检查方法,ReflectionParameter 对象可以用于检查类中的方法,该对象可以告诉你参数的名称,变量是否可以按引用传递,还可以告诉你参数类型提示和方法是否接受空值作为参数。

获得 ReflectionParameter 对象的方法有同样两种,这和获取 ReflectionMethod 对象非常类似:

第一种是通过 ReflectionMethod::getParameters() 方法返回 ReflectionParameter 对象数组,这种方法可以获取到一个方法的全部参数对象。

第二种是直接使用 ReflectionParameter 类实例化获取对象,这种方法只能获取到单一参数的对象。

ReflectionParameter 对象的工具方法:

ReflectionParameter::allowsNull — Checks if null is allowed

ReflectionParameter::canBePassedByValue — Returns whether this parameter can be passed by value

ReflectionParameter::__clone — Clone

ReflectionParameter::__construct — Construct

ReflectionParameter::export — Exports

ReflectionParameter::getClass — Get the type hinted class

ReflectionParameter::getDeclaringClass — Gets declaring class

ReflectionParameter::getDeclaringFunction — Gets declaring function

ReflectionParameter::getDefaultValue — Gets default parameter value

ReflectionParameter::getDefaultValueConstantName — Returns the default value's constant name if default value is constant or null

ReflectionParameter::getName — Gets parameter name

ReflectionParameter::getPosition — Gets parameter position

ReflectionParameter::getType — Gets a parameter's type

ReflectionParameter::hasType — Checks if parameter has a type

ReflectionParameter::isArray — Checks if parameter expects an array

ReflectionParameter::isCallable — Returns whether parameter MUST be callable

ReflectionParameter::isDefaultValueAvailable — Checks if a default value is available

ReflectionParameter::isDefaultValueConstant — Returns whether the default value of this parameter is constant

ReflectionParameter::isOptional — Checks if optional

ReflectionParameter::isPassedByReference — Checks if passed by reference

ReflectionParameter::isVariadic — Checks if the parameter is variadic

ReflectionParameter::__toString — To string

ReflectionMethod::getParameters

$method = new ReflectionMethod('Student', 'setName');

$params = $method->getParameters();

var_dump($params);

结语

php的反射API功能非常的强大,它可以将一个类的详细信息获取出来。我们可以通过反射API编写个类来动态调用Module对象,该类可以自由加载第三方插件并集成进已有的系统。而不需要把第三方的代码硬编码进原有的代码中。虽然实际开发中使用反射情况比较少,但了解反射API对工作中对代码结构的了解和开发业务模式帮助还是非常大的。

PHP中的反射API就像Java中的java.lang.reflect包一样。它由一系列可以分析属性、方法和类的内置类组成。它在某些方面和对象函数相似,比如get_class_vars(),但是更加灵活,而且可以提供更多信息。反射API也可与PHP最新的面向对象特性一起工作,如访问控制、接口和抽象类。旧的类函数则不太容易与这些新特性一起使用。看过框架源码的朋友应该对PHP的反射机制有一定的了解,像是依赖注入,对象池,类加载,一些设计模式等等,都用到了反射机制。



推荐阅读
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 有没有一种方法可以在不继承UIAlertController的子类或不涉及UIAlertActions的情况下 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
author-avatar
sueann88314_254
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有