实例介绍PHP的Reflection反射机制


Posted in PHP onAugust 05, 2014

PHP5添加了一项新的功能:Reflection。这个功能使得程序员可以reverse-engineer class, interface,function,method and extension。通过PHP代码,就可以得到某object的所有信息,并且可以和它交互。
假设有一个类Person:

class Person {  

 /** 

     * For the sake of demonstration, we"re setting this private

     */ 

    private $_allowDynamicAttributes = false;

 

    /** type=primary_autoincrement */

    protected $id = 0;

 

    /** type=varchar length=255 null */

    protected $name;

 

    /** type=text null */

    protected $biography;

 

        public function getId()

        {

         return $this->id;

        }

        public function setId($v)

        {

            $this->id = $v;

        }

        public function getName()

        {

         return $this->name;

        }

        public function setName($v)

        {

          $this->name = $v;

        }

        public function getBiography()

        {

           return $this->biography;

        }

        public function setBiography($v)

        {

          $this->biography = $v;

        }

}

通过ReflectionClass,我们可以得到Person类的以下信息:
1.常量 Contants
2.属性 Property Names
3.方法 Method Names
4.静态属性 Static Properties
5.命名空间 Namespace
6.Person类是否为final或者abstract

只要把类名"Person"传递给ReflectionClass就可以了:

$class = new ReflectionClass('Person');

获取属性(Properties):

$properties = $class->getProperties();

foreach($properties as $property) {

    echo $property->getName()."\n";

}

// 输出:

// _allowDynamicAttributes

// id

// name

// biography

默认情况下,ReflectionClass会获取到所有的属性,private 和 protected的也可以。如果只想获取到private属性,就要额外传个参数:

$private_properties = $class->getProperties(ReflectionProperty::IS_PRIVATE);

可用参数列表:

ReflectionProperty::IS_STATIC

ReflectionProperty::IS_PUBLIC

ReflectionProperty::IS_PROTECTED

ReflectionProperty::IS_PRIVATE

如果要同时获取public 和private 属性,就这样写:ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED
应该不会感觉陌生吧。

通过$property->getName()可以得到属性名,通过getDocComment可以得到写给property的注释。

foreach($properties as $property) {

    if($property->isProtected()) {

        $docblock = $property->getDocComment();

        preg_match('/ type\=([a-z_]*) /', $property->getDocComment(), $matches);

        echo $matches[1]."\n";

    }

}

// Output:

// primary_autoincrement

// varchar

// text

有点不可思议了吧。竟然连注释都可以取到。
获取方法(methods):通过getMethods() 来获取到类的所有methods。返回的是ReflectionMethod对象的数组。不再演示。
最后通过ReflectionMethod来调用类里面的method。

$data = array("id" => 1, "name" => "Chris", "biography" => "I am am a PHP developer");

foreach($data as $key => $value) {

    if(!$class->hasProperty($key)) {

        throw new Exception($key." is not a valid property");

    }

 

    if(!$class->hasMethod("get".ucfirst($key))) {

        throw new Exception($key." is missing a getter");

    }

 

    if(!$class->hasMethod("set".ucfirst($key))) {

        throw new Exception($key." is missing a setter");

    }

 

    // Make a new object to interact with

    $object = new Person();

 

    // Get the getter method and invoke it with the value in our data array

    $setter = $class->getMethod("set".ucfirst($key));

    $ok = $setter->invoke($object, $value);

 

    // Get the setter method and invoke it

    $setter = $class->getMethod("get".ucfirst($key));

    $objValue = $setter->invoke($object);

 

    // Now compare

    if($value == $objValue) {

        echo "Getter or Setter has modified the data.\n";

    } else {

        echo "Getter and Setter does not modify the data.\n";

   }

}

有点意思吧。

PHP 相关文章推荐
php 移除数组重复元素的一点说明
Nov 27 PHP
PHP 删除一个目录及目录下的所有文件的函数代码
May 26 PHP
PHP 文件编程综合案例-文件上传的实现
Jul 03 PHP
PHP版微信公众平台红包API
Apr 02 PHP
7个鲜为人知却非常实用的PHP函数
Jul 01 PHP
使用Huagepage和PGO来提升PHP7的执行性能
Nov 30 PHP
配置eAccelerator和XCache扩展来加速PHP程序的执行
Dec 22 PHP
PHP多维数组转一维数组的简单实现方法
Dec 23 PHP
php session的应用详细介绍
Mar 22 PHP
thinkPHP框架实现生成条形码的方法示例
Jun 06 PHP
Yii2语言国际化的配置教程
Aug 19 PHP
php JWT在web端中的使用方法教程
Sep 06 PHP
PHP中读取文件的8种方法和代码实例
Aug 05 #PHP
PHP中Fatal error session_start()错误解决步骤
Aug 05 #PHP
PHP学习笔记(二) 了解PHP的基本语法以及目录结构
Aug 04 #PHP
PHP学习笔记(一) 简单了解PHP
Aug 04 #PHP
linux下安装php的memcached客户端
Aug 03 #PHP
Linux下创建nginx脚本-start、stop、reload…
Aug 03 #PHP
Linux下php5.4启动脚本
Aug 03 #PHP
You might like
php中取得文件的后缀名?
2012/02/20 PHP
php使用ereg验证文件上传的方法
2014/12/16 PHP
PHP对文件进行加锁、解锁实例
2015/01/23 PHP
判断多个input type=file是否有已经选择好文件的代码
2012/05/23 Javascript
主页面中的两个iframe实现鼠标拖动改变其大小
2013/04/16 Javascript
javascript 弹出的窗口返回值给父窗口具体实现
2013/11/23 Javascript
基于NodeJS的前后端分离的思考与实践(六)Nginx + Node.js + Java 的软件栈部署实践
2014/09/26 NodeJs
js字符串完全替换函数分享
2014/12/03 Javascript
JavaScript中的Math.sin()方法使用详解
2015/06/15 Javascript
jquery简单插件制作(fn.extend)完整实例
2016/05/24 Javascript
JavaScript 函数节流详解及方法总结
2017/02/09 Javascript
学习使用jQuery表单验证插件和日历插件
2017/02/13 Javascript
详解让sublime text3支持Vue语法高亮显示的示例
2017/09/29 Javascript
微信小程序自动客服功能
2017/11/02 Javascript
js点击时关闭该范围下拉菜单之外的菜单方法
2018/01/11 Javascript
简单的Vue SSR的示例代码
2018/01/12 Javascript
Vue子组件向父组件通信与父组件调用子组件中的方法
2018/06/22 Javascript
vue.js中proxyTable 转发请求的实现方法
2018/09/20 Javascript
eslint 的三大通用规则详解
2019/05/16 Javascript
[02:50]【扭转乾坤,只此一招】DOTA2永雾林渊版本开启新篇章
2020/12/22 DOTA
Python 实现简单的电话本功能
2015/08/09 Python
Python压缩解压缩zip文件及破解zip文件密码的方法
2015/11/04 Python
python 开发的三种运行模式详细介绍
2017/01/18 Python
使用python进行文本预处理和提取特征的实例
2018/06/05 Python
深入了解Python iter() 方法的用法
2019/07/11 Python
Python实现疫情通定时自动填写功能(附代码)
2020/05/27 Python
python图片验证码识别最新模块muggle_ocr的示例代码
2020/07/03 Python
Python基于traceback模块获取异常信息
2020/07/23 Python
python 两种方法删除空文件夹
2020/09/29 Python
2014婚礼司仪主持词
2014/03/14 职场文书
操行评语大全
2014/04/30 职场文书
2014年小学数学工作总结
2014/12/12 职场文书
2014年干部培训工作总结
2014/12/17 职场文书
大学团日活动总结书
2015/05/11 职场文书
创业开店,这样方式更合理
2019/08/26 职场文书
PHP判断是否是json字符串
2021/04/01 PHP