实例介绍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开发过程中关于继承的使用方法分享
Jun 17 PHP
解析php二分法查找数组是否包含某一元素
May 23 PHP
ThinkPHP页面跳转success与error方法概述
Jun 25 PHP
PHP中的gzcompress、gzdeflate、gzencode函数详解
Jul 29 PHP
php数组索引的Key加引号和不加引号的区别
Aug 19 PHP
php防止恶意刷新与刷票的方法
Nov 21 PHP
php计算2个日期的差值函数分享
Feb 02 PHP
PHP实现获取并生成数据库字典的方法
May 04 PHP
PHP创建多级目录的两种方法
Oct 28 PHP
PHP完全二叉树定义与实现方法示例
Oct 09 PHP
PHP双向链表定义与用法示例
Jan 31 PHP
深入理解 PHP7 中全新的 zval 容器和引用计数机制
Oct 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
Zend Framework中的简单工厂模式 图文
2012/07/10 PHP
PHP检查网站是否宕机的方法示例
2017/07/24 PHP
JS获取iframe中longdesc属性的方法
2015/04/01 Javascript
jquery实现表单输入时提示文字滑动向上效果
2015/08/10 Javascript
jQuery 自定义下拉框(DropDown)附源码下载
2016/07/22 Javascript
基于jQuery实现页面搜索功能
2020/03/26 Javascript
微信小程序 开发指南详解
2016/09/27 Javascript
bootstrap中的 form表单属性role="form"的作用详解
2017/01/20 Javascript
jquery dataTable 获取某行数据
2017/05/05 jQuery
jquery基于layui实现二级联动下拉选择(省份城市选择)
2017/06/20 jQuery
浅谈react 同构之样式直出
2017/11/07 Javascript
解决在Bootstrap模糊框中使用WebUploader的问题
2018/03/22 Javascript
Vue实现移动端左右滑动效果的方法
2018/11/27 Javascript
详解关于React-Router4.0跳转不置顶解决方案
2019/05/10 Javascript
vue 关闭浏览器窗口的时候,清空localStorage的数据示例
2019/11/06 Javascript
vue之debounce属性被移除及处理详解
2019/11/13 Javascript
详解vue 中 scoped 样式作用域的规则
2020/09/14 Javascript
[03:48]显微镜下的DOTA2第四期——TP动作
2014/06/20 DOTA
[06:40]2014DOTA2西雅图国际邀请赛 DK战队巡礼
2014/07/07 DOTA
30分钟搭建Python的Flask框架并在上面编写第一个应用
2015/03/30 Python
Python进阶学习之特殊方法实例详析
2017/12/01 Python
Python访问MongoDB,并且转换成Dataframe的方法
2018/10/15 Python
python2.7使用plotly绘制本地散点图和折线图
2019/04/02 Python
Python学习笔记之While循环用法分析
2019/08/14 Python
Python 中 -m 的典型用法、原理解析与发展演变
2019/11/11 Python
Python高级property属性用法实例分析
2019/11/19 Python
详解Python Opencv和PIL读取图像文件的差别
2019/12/27 Python
python2 对excel表格操作完整示例
2020/02/23 Python
美国背景检查、公共记录和人物搜索网站:BeenVerified
2018/02/25 全球购物
乌克兰机票、铁路和巴士票、酒店搜索、保险:Tickets.ua
2020/01/11 全球购物
农田水利实习自我鉴定
2013/09/19 职场文书
应聘编辑职位自荐信范文
2014/01/05 职场文书
技术总监管理岗位职责
2014/03/09 职场文书
毕业生面试求职信
2014/06/23 职场文书
大学毕业典礼致辞
2015/07/29 职场文书
Nginx部署vue项目和配置代理的问题解析
2021/08/04 Servers