实例介绍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 相关文章推荐
使用adodb lite解决问题
Dec 31 PHP
PHP5中的时间相差8小时的解决办法
Mar 28 PHP
php 时间计算问题小结
Jan 04 PHP
解析web文件操作常见安全漏洞(目录、文件名检测漏洞)
Jun 29 PHP
PHP判断字符串长度的两种方法很实用
Sep 22 PHP
mysql desc(DESCRIBE)命令实例讲解
Sep 24 PHP
详解PHP编码转换函数应用技巧
Oct 22 PHP
PHP编程计算两个时间段是否有交集的实现方法(不算边界重叠)
May 30 PHP
PHP类与对象后期静态绑定操作实例详解
Dec 20 PHP
详解PHP实现支付宝小程序用户授权的工具类
Dec 25 PHP
Laravel框架实现的上传图片到七牛功能详解
Sep 06 PHP
thinkphp框架实现路由重定义简化url访问地址的方法分析
Apr 04 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中的switch语句的用法实例详解
2015/10/21 PHP
CI框架表单验证实例详解
2016/11/21 PHP
基于laravel-admin 后台 列表标签背景的使用方法
2019/10/03 PHP
javascript 面向对象全新理练之继承与多态
2009/12/03 Javascript
浅析LigerUi开发中谨慎载入common.css文件
2013/07/09 Javascript
javascript使用定时函数实现跳转到某个页面
2013/12/25 Javascript
JavaScript弹出新窗口并控制窗口移动到指定位置的方法
2015/04/06 Javascript
js实现点击向下展开的下拉菜单效果代码
2015/09/01 Javascript
angularjs表格分页功能详解
2016/01/21 Javascript
Bootstrap每天必学之响应式导航、轮播图
2016/04/25 Javascript
Web前端新人笔记之jquery入门心得(新手必看)
2016/05/17 Javascript
关于Jquery中的bind(),on()绑定事件方式总结
2016/10/26 Javascript
JavaScript之Vue.js【入门基础】
2016/12/06 Javascript
JavaWeb表单及时验证功能在输入后立即验证(含用户类型,性别,爱好...的验证)
2017/06/09 Javascript
JavaScript 程序错误Cannot use 'in' operator to search的解决方法
2017/07/10 Javascript
vue 打包后的文件部署到express服务器上的方法
2017/08/09 Javascript
vue.js 添加 fastclick的支持方法
2018/08/28 Javascript
js实现图片放大并跟随鼠标移动特效
2019/01/18 Javascript
JavaScript实现的3D旋转魔方动画效果实例代码
2019/07/31 Javascript
js实现旋转木马轮播图效果
2020/01/10 Javascript
vue 解决mintui弹窗弹起来,底部页面滚动bug问题
2020/11/12 Javascript
[01:10]3.19DOTA2发布会 三代刀塔人第一代
2014/03/25 DOTA
使用PYTHON接收多播数据的代码
2012/03/01 Python
用Python创建声明性迷你语言的教程
2015/04/13 Python
Python验证文件是否可读写代码分享
2017/12/11 Python
Python实现可获取网易页面所有文本信息的网易网络爬虫功能示例
2018/01/15 Python
python操作excel的方法
2018/08/16 Python
详解用pyecharts Geo实现动态数据热力图城市找不到问题解决
2019/06/26 Python
python 画函数曲线示例
2019/12/04 Python
Django多进程滚动日志问题解决方案
2019/12/17 Python
Python使用re模块验证危险字符
2020/05/21 Python
世嘉游戏英国官方商店:SEGA Shop UK
2019/09/20 全球购物
心理健康教育心得体会
2013/12/29 职场文书
教师业务培训方案
2014/05/01 职场文书
单位租房协议范本
2014/12/03 职场文书
小学班主任个人总结
2015/03/03 职场文书