• 售前

  • 售后

热门帖子
入门百科

PHP反射机制案例讲解

[复制链接]
123456811 显示全部楼层 发表于 2021-8-14 15:17:48 |阅读模式 打印 上一主题 下一主题
简介

就算是类成员界说为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,都可以获取到。
  1. <?php
  2. namespace Extend;
  3. use ReflectionClass;
  4. use Exception;
  5. /**
  6. * 用户相关类
  7. * Class User
  8. * @package Extend
  9. */
  10. class User{
  11.     const ROLE = 'Students';
  12.     public $username = '';
  13.     private $password = '';
  14.     public function __construct($username, $password)
  15.     {
  16.         $this->username = $username;
  17.         $this->password = $password;
  18.     }
  19.     /**
  20.      * 获取用户名
  21.      * @return string
  22.      */
  23.     public function getUsername()
  24.     {
  25.         return $this->username;
  26.     }
  27.     /**
  28.      * 设置用户名
  29.      * @param string $username
  30.      */
  31.     public function setUsername($username)
  32.     {
  33.         $this->username = $username;
  34.     }
  35.     /**
  36.      * 获取密码
  37.      * @return string
  38.      */
  39.     private function getPassword()
  40.     {
  41.         return $this->password;
  42.     }
  43.     /**
  44.      * 设置密码
  45.      * @param string $password
  46.      */
  47.     private function setPassowrd($password)
  48.     {
  49.         $this->password = $password;
  50.     }
  51. }
  52. $class = new ReflectionClass('Extend\User');  // 将类名User作为参数,即可建立User类的反射类
  53. $properties = $class->getProperties();  // 获取User类的所有属性,返回ReflectionProperty的数组
  54. $property = $class->getProperty('password'); // 获取User类的password属性ReflectionProperty
  55. $methods = $class->getMethods();   // 获取User类的所有方法,返回ReflectionMethod数组
  56. $method = $class->getMethod('getUsername');  // 获取User类的getUsername方法的ReflectionMethod
  57. $constants = $class->getConstants();   // 获取所有常量,返回常量定义数组
  58. $constant = $class->getConstant('ROLE');   // 获取ROLE常量
  59. $namespace = $class->getNamespaceName();  // 获取类的命名空间
  60. $comment_class = $class->getDocComment();  // 获取User类的注释文档,即定义在类之前的注释
  61. $comment_method = $class->getMethod('getUsername')->getDocComment();  // 获取User类中getUsername方法的注释文档
复制代码
留意:创建反射类时传送的类名,必须包含完整的定名空间,即使利用了 use 关键字。否则找不到类名会抛出非常。
交互

一旦创建了反射类的实例,我们不但可以通过反射类访问原来类的方法和属性,还能创建原来类的实例或则直接调用类内里的方法。
  1. $class = new ReflectionClass('Extend\User');  // 将类名User作为参数,即可建立User类的反射类
  2. $instance = $class->newInstance('youyou', 1, '***');  // 创建User类的实例
  3. $instance->setUsername('youyou_2');  // 调用User类的实例调用setUsername方法设置用户名
  4. $value = $instance->getUsername();   // 用过User类的实例调用getUsername方法获取用户名
  5. echo $value;echo "\n";   // 输出 youyou_2
  6. $class->getProperty('username')->setValue($instance, 'youyou_3');  // 通过反射类ReflectionProperty设置指定实例的username属性值
  7. $value = $class->getProperty('username')->getValue($instance);  // 通过反射类ReflectionProperty获取username的属性值
  8. echo $value;echo "\n";   // 输出 youyou_3
  9. $class->getMethod('setUsername')->invoke($instance, 'youyou_4'); // 通过反射类ReflectionMethod调用指定实例的方法,并且传送参数
  10. $value = $class->getMethod('getUsername')->invoke($instance);    // 通过反射类ReflectionMethod调用指定实例的方法
  11. echo $value;echo "\n";   // 输出 youyou_4
  12. try {
  13.     $property = $class->getProperty('password_1');
  14.     $property->setAccessible(true);   // 修改 $property 对象的可访问性
  15.     $property->setValue($instance, 'password_2');  // 可以执行
  16.     $value = $property->getValue($instance);     // 可以执行
  17.     echo $value;echo "\n";   // 输出 password_2
  18.     $class->getProperty('password')->setAccessible(true);    // 修改临时ReflectionProperty对象的可访问性
  19.     $class->getProperty('password')->setValue($instance, 'password');// 不能执行,抛出不能访问异常
  20.     $value = $class->getProperty('password')->getValue($instance);   // 不能执行,抛出不能访问异常
  21.     $value = $instance->password;   // 不能执行,类本身的属性没有被修改,仍然是private
  22. }catch(Exception $e){echo $e;}
复制代码
留意事项

       
  • 直接访问 protected 或则 private 的熟悉大概方法会抛出非常   
  • 须要调用指定的 ReflectionProperty 或则 ReflectionMethod 对象 setAccessible(true)方法才气访问非公有成员   
  • 修改非公有成员的访问权限只作用于当前的反射类的实例   
  • 须要留意获取静态成员和非静态成员所利用的方法不一样   
  • 获取父类成员的方法和一般的不一样
偶然间会整理出反射类的API表,详细的API列表可以先查阅官方文档。
到此这篇关于PHP反射机制案例解说的文章就先容到这了,更多相关PHP反射机制内容请搜索脚本之家从前的文章或继承欣赏下面的相关文章渴望各人以后多多支持脚本之家!

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作