您现在的位置是:群英 > 开发技术 > PHP语言
PHP反射机制是什么?反射类型有哪些?
Admin发表于 2021-10-29 18:00:24971 次浏览

    这篇文章给大家分享的是PHP反射机制的内容,一些朋友可能对于PHP反射机制不是很了解,对此本文通过简要的PHP反射机制案例给大家讲讲是什么PHP反射机制,文中示例代码介绍的非常详细,感兴趣的朋友接下来一起跟随小编一起学习一下吧。

    就算是类成员定义为private也可以在外部访问,不用创建类的实例也可以访问类的成员和方法。

    PHP自5.0版本以后添加了反射机制,它提供了一套强大的反射API,允许你在PHP运行环境中,访问和使用类、方法、属性、参数和注释等,其功能十分强大,经常用于高扩展的PHP框架,自动加载插件,自动生成文档,甚至可以用来扩展PHP语言。由于它是PHP內建的oop扩展,为语言本身自带的特性,所以不需要额外添加扩展或者配置就可以使用。

    反射类型

    PHP反射API会基于类,方法,属性,参数等维护相应的反射类,已提供相应的调用API。

类型 说明
Reflector Reflector 是一个接口,被所有可导出的反射类所实现(implement)
Reflection 反射(reflection)类
ReflectionClass 报告了一个类的有关信息
ReflectionZendExtension 报告Zend扩展的相关信息
ReflectionExtension 报告了PHP扩展的有关信息
ReflectionFunction 报告了一个函数的有关信息
ReflectionFunctionAbstract ReflectionFunction 的父类
ReflectionMethod 报告了一个方法的有关信息
ReflectionObject 报告了一个对象(object)的相关信息
ReflectionParameter 取回了函数或方法参数的相关信息
ReflectionProperty 报告了类的属性的相关信息

    访问

    假设定义了一个类 User,我们首先需要建立这个类的反射类实例,然后基于这个实例可以访问 User 中的属性或者方法。不管类中定义的成员权限声明是否为public,都可以获取到。

<?php 
namespace Extend;

use ReflectionClass;
use Exception;

/**
 * 用户相关类
 * Class User
 * @package Extend
 */
class User{
    const ROLE = 'Students';
    public $username = '';
    private $password = '';

    public function __construct($username, $password)
    {
        $this->username = $username;
        $this->password = $password;
    }

    /**
     * 获取用户名
     * @return string
     */
    public function getUsername()
    {
        return $this->username;
    }

    /**
     * 设置用户名
     * @param string $username
     */
    public function setUsername($username)
    {
        $this->username = $username;
    }

    /**
     * 获取密码
     * @return string
     */
    private function getPassword()
    {
        return $this->password;
    }

    /**
     * 设置密码
     * @param string $password
     */
    private function setPassowrd($password)
    {
        $this->password = $password;
    }
}

$class = new ReflectionClass('Extend\User');  // 将类名User作为参数,即可建立User类的反射类
$properties = $class->getProperties();  // 获取User类的所有属性,返回ReflectionProperty的数组
$property = $class->getProperty('password'); // 获取User类的password属性ReflectionProperty
$methods = $class->getMethods();   // 获取User类的所有方法,返回ReflectionMethod数组
$method = $class->getMethod('getUsername');  // 获取User类的getUsername方法的ReflectionMethod
$constants = $class->getConstants();   // 获取所有常量,返回常量定义数组
$constant = $class->getConstant('ROLE');   // 获取ROLE常量
$namespace = $class->getNamespaceName();  // 获取类的命名空间
$comment_class = $class->getDocComment();  // 获取User类的注释文档,即定义在类之前的注释
$comment_method = $class->getMethod('getUsername')->getDocComment();  // 获取User类中getUsername方法的注释文档

    注意:创建反射类时传送的类名,必须包含完整的命名空间,即使使用了 use 关键字。否则找不到类名会抛出异常。

    交互

    一旦创建了反射类的实例,我们不仅可以通过反射类访问原来类的方法和属性,还能创建原来类的实例或则直接调用类里面的方法。

$class = new ReflectionClass('Extend\User');  // 将类名User作为参数,即可建立User类的反射类
$instance = $class->newInstance('youyou', 1, '***');  // 创建User类的实例

$instance->setUsername('youyou_2');  // 调用User类的实例调用setUsername方法设置用户名
$value = $instance->getUsername();   // 用过User类的实例调用getUsername方法获取用户名
echo $value;echo "\n";   // 输出 youyou_2

$class->getProperty('username')->setValue($instance, 'youyou_3');  // 通过反射类ReflectionProperty设置指定实例的username属性值
$value = $class->getProperty('username')->getValue($instance);  // 通过反射类ReflectionProperty获取username的属性值
echo $value;echo "\n";   // 输出 youyou_3

$class->getMethod('setUsername')->invoke($instance, 'youyou_4'); // 通过反射类ReflectionMethod调用指定实例的方法,并且传送参数
$value = $class->getMethod('getUsername')->invoke($instance);    // 通过反射类ReflectionMethod调用指定实例的方法
echo $value;echo "\n";   // 输出 youyou_4

try {
    $property = $class->getProperty('password_1');
    $property->setAccessible(true);   // 修改 $property 对象的可访问性
    $property->setValue($instance, 'password_2');  // 可以执行
    $value = $property->getValue($instance);     // 可以执行
    echo $value;echo "\n";   // 输出 password_2
    $class->getProperty('password')->setAccessible(true);    // 修改临时ReflectionProperty对象的可访问性
    $class->getProperty('password')->setValue($instance, 'password');// 不能执行,抛出不能访问异常
    $value = $class->getProperty('password')->getValue($instance);   // 不能执行,抛出不能访问异常
    $value = $instance->password;   // 不能执行,类本身的属性没有被修改,仍然是private
}catch(Exception $e){echo $e;}

    注意事项

  1. 直接访问 protected 或则 private 的熟悉或者方法会抛出异常
  2. 需要调用指定的 ReflectionProperty 或则 ReflectionMethod 对象 setAccessible(true)方法才能访问非公有成员
  3. 修改非公有成员的访问权限只作用于当前的反射类的实例
  4. 需要注意获取静态成员和非静态成员所使用的方法不一样
  5. 获取父类成员的方法和一般的不一样

    关于PHP反射机制的内容就介绍到这,本文的PHP反射机制案例讲解值得参考,感兴趣的朋友可以了解看看,希望对大家有学习PHP帮助,想要了解更多大家可以关注其它的相关文章。

文本转载自脚本之家

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

标签: PHP反射机制
相关信息推荐
2022-09-05 17:40:09 
摘要:这篇文章主要介绍了Yii框架应用组件用法,结合实例形式分析了Yii应用组件基本功能、定义、使用方法及操作注意事项,需要的朋友可以参考下
2022-07-04 17:29:47 
摘要:这篇文章主要为大家介绍了Go语言基础Go语言数组的用法及示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-12-24 11:46:35 
摘要:在php中,可以利用count()或sizeof()函数来求二维数组有多少个元素;这两个函数都能统计二维数组中的元素数目,语法“count($arr,$m)”或“sizeof($arr,$m)”,只需要将参数“$m”的值设置为“1”或者“COUNT_RECURSIVE”即可递归计算数组中元素的个数。
云活动
推荐内容
热门关键词
热门信息
群英网络助力开启安全的云计算之旅
立即注册,领取新人大礼包
  • 联系我们
  • 24小时售后:4006784567
  • 24小时TEL :0668-2555666
  • 售前咨询TEL:400-678-4567

  • 官方微信

    官方微信
Copyright  ©  QY  Network  Company  Ltd. All  Rights  Reserved. 2003-2019  群英网络  版权所有   茂名市群英网络有限公司
增值电信经营许可证 : B1.B2-20140078   粤ICP备09006778号
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
微信公众号
返回顶部
返回顶部 返回顶部