实例介绍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 相关文章推荐
基于文本的搜索
Oct 09 PHP
PHP MYSQL乱码问题,使用SET NAMES utf8校正
Nov 30 PHP
php 获取全局变量的代码
Apr 21 PHP
组合算法的PHP解答方法
Feb 04 PHP
深入理解PHP之数组(遍历顺序)  Laruence原创
Jun 13 PHP
php.ini-dist 和 php.ini-recommended 的区别介绍(方便开发与安全的朋友)
Jul 01 PHP
计算php页面运行时间的函数介绍
Jul 01 PHP
PHP中执行cmd命令的方法
Oct 11 PHP
跟我学Laravel之配置Laravel
Oct 15 PHP
PHP中使用php5-ffmpeg撷取视频图片实例
Jan 07 PHP
PHP限制HTML内容中图片必须是本站的方法
Jun 16 PHP
php 三元运算符实例详细介绍
Dec 15 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实现memcache缓存示例讲解
2013/12/04 PHP
PHP eval函数使用介绍
2013/12/08 PHP
PHP错误机制知识汇总
2016/03/24 PHP
PHP中in_array函数使用的问题与解决办法
2016/09/11 PHP
PHP实现的redis主从数据库状态检测功能示例
2017/07/20 PHP
PHP开发的文字水印,缩略图,图片水印实现类与用法示例
2019/04/12 PHP
Thinkphp 框架扩展之Widget扩展实现方法分析
2020/04/23 PHP
PHP网站常见安全漏洞,及相应防范措施总结
2021/03/01 PHP
jQuery 美元符冲突的解决方法
2010/03/28 Javascript
腾讯与新浪的通过IP地址获取当前地理位置(省份)的接口
2010/07/26 Javascript
jquery实现表格奇数偶数行不同样式(有图为证及实现代码)
2013/01/23 Javascript
NodeJs中的VM模块详解
2015/05/06 NodeJs
Javascript实现飞动广告效果的方法
2015/05/25 Javascript
将JSON字符串转换成Map对象的方法
2016/11/30 Javascript
jQuery UI仿淘宝搜索下拉列表功能
2017/01/10 Javascript
JavaScript之排序函数_动力节点Java学院整理
2017/06/30 Javascript
浅谈在vue中用webpack打包之后运行文件的问题以及相关配置方法
2018/02/21 Javascript
webpack打包node.js后端项目的方法
2018/03/10 Javascript
Vue.js实现表格渲染的方法
2018/09/07 Javascript
vue webpack开发访问后台接口全局配置的方法
2018/09/18 Javascript
React中this丢失的四种解决方法
2019/03/12 Javascript
小程序云开发获取不到数据库记录的解决方法
2019/05/18 Javascript
Vue侦测相关api的实现方法
2019/05/22 Javascript
vue实现导航菜单和编辑文本的示例代码
2020/07/04 Javascript
Vue中keep-alive组件的深入理解
2020/08/23 Javascript
Openlayers测量距离与面积的实现方法
2020/09/25 Javascript
vscode 远程调试python的方法
2017/12/01 Python
Python面向对象程序设计OOP入门教程【类,实例,继承,重载等】
2019/01/05 Python
将tf.batch_matmul替换成tf.matmul的实现
2020/06/18 Python
python 爬取小说并下载的示例
2020/12/07 Python
法国和欧洲海边和滑雪度假:Pierre & Vacances
2017/01/04 全球购物
关于护士节的演讲稿
2014/05/26 职场文书
雷锋式好少年事迹材料
2014/08/17 职场文书
2014年营销工作总结
2014/11/22 职场文书
关于空气污染危害的感想
2015/08/11 职场文书
一次线上mongo慢查询问题排查处理记录
2022/03/18 MongoDB