热门标签 | 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的反射机制有一定的了解,像是依赖注入,对象池,类加载,一些设计模式等等,都用到了反射机制。



推荐阅读
  • 本文介绍如何使用阿里云的fastjson库解析包含时间戳、IP地址和参数等信息的JSON格式文本,并进行数据处理和保存。 ... [详细]
  • andr ... [详细]
  • 本文详细探讨了VxWorks操作系统中双向链表和环形缓冲区的实现原理及使用方法,通过具体示例代码加深理解。 ... [详细]
  • Scala 实现 UTF-8 编码属性文件读取与克隆
    本文介绍如何使用 Scala 以 UTF-8 编码方式读取属性文件,并实现属性文件的克隆功能。通过这种方式,可以确保配置文件在多线程环境下的一致性和高效性。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 本文详细介绍了 Java 中 org.apache.xmlbeans.SchemaType 类的 getBaseEnumType() 方法,提供了多个代码示例,并解释了其在不同场景下的使用方法。 ... [详细]
  • 深入理解Java泛型:JDK 5的新特性
    本文详细介绍了Java泛型的概念及其在JDK 5中的应用,通过具体代码示例解释了泛型的引入、作用和优势。同时,探讨了泛型类、泛型方法和泛型接口的实现,并深入讲解了通配符的使用。 ... [详细]
  • 本文介绍了两种方法,用于检测 Android 设备是否开启了开发者模式。第一种方法通过检查 USB 调试模式的状态,第二种方法则直接判断开发者选项是否启用。这两种方法均提供了代码示例和详细解释。 ... [详细]
  • 本文介绍如何使用JPA Criteria API创建带有多个可选参数的动态查询方法。当某些参数为空时,这些参数不会影响最终查询结果。 ... [详细]
  • 并发编程:深入理解设计原理与优化
    本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ... [详细]
  • 本文详细介绍了中央电视台电影频道的节目预告,并通过专业工具分析了其加载方式,确保用户能够获取最准确的电视节目信息。 ... [详细]
  • 本文探讨了《魔兽世界》中红蓝两方阵营在备战阶段的策略与实现方法,通过代码展示了双方如何根据资源和兵种特性进行战士生产。 ... [详细]
  • 毕业设计:基于机器学习与深度学习的垃圾邮件(短信)分类算法实现
    本文详细介绍了如何使用机器学习和深度学习技术对垃圾邮件和短信进行分类。内容涵盖从数据集介绍、预处理、特征提取到模型训练与评估的完整流程,并提供了具体的代码示例和实验结果。 ... [详细]
  • 在多线程编程环境中,线程之间共享全局变量可能导致数据竞争和不一致性。为了解决这一问题,Linux提供了线程局部存储(TLS),使每个线程可以拥有独立的变量副本,确保线程间的数据隔离与安全。 ... [详细]
  • 本文介绍如何在Java项目中使用Log4j库进行日志记录。我们将详细说明Log4j库的引入、配置及简单应用,帮助开发者快速上手。 ... [详细]
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社区 版权所有