实例介绍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 相关文章推荐
Content-type 的说明
Oct 09 PHP
php+dojo 的数据库保存拖动布局的一个方法dojo 这里下载
Mar 07 PHP
Apache+php+mysql在windows下的安装与配置图解(最新版)
Nov 30 PHP
PHP pathinfo()获得文件的路径、名称等信息说明
Sep 13 PHP
php unset全局变量运用问题的深入解析
Jun 17 PHP
php 检查电子邮件函数(自写)
Jan 16 PHP
PHP实现过滤各种HTML标签
May 17 PHP
为你总结一些php系统类函数
Oct 21 PHP
如何使用GDB调试PHP程序
Dec 08 PHP
简介WordPress中用于获取首页和站点链接的PHP函数
Dec 17 PHP
分享PHP守护进程类
Dec 30 PHP
php版交通银行网银支付接口开发入门教程
Sep 26 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数组函数序列之each() - 获取数组当前内部指针所指向元素的键名和键值,并将指针移到下一位
2011/10/31 PHP
基于magic_quotes_gpc与magic_quotes_runtime的区别与使用介绍
2013/04/22 PHP
浅谈web上存漏洞及原理分析、防范方法(安全文件上存方法)
2013/06/29 PHP
根据中文裁减字符串函数的php代码
2013/12/03 PHP
Centos下升级php5.2到php5.4全记录(编译安装)
2015/04/03 PHP
php获取英文姓名首字母的方法
2015/07/13 PHP
JS 屏蔽按键效果与改变按键效果的示例代码
2013/12/24 Javascript
JavaScript页面模板库handlebars的简单用法
2015/03/02 Javascript
javascript中返回顶部按钮的实现
2015/05/05 Javascript
jQuery+CSS3实现3D立方体旋转效果
2015/11/10 Javascript
判断js的Array和Object的实现方法
2016/08/29 Javascript
js中的eval()函数把含有转义字符的字符串转换成Object对象的方法
2016/12/02 Javascript
javascript动画之磁性吸附效果篇
2016/12/09 Javascript
zTree异步加载展开第一级节点的实现方法
2017/09/05 Javascript
jQury Ajax使用Token验证身份实例代码
2017/09/22 Javascript
Node.js使用MySQL连接池的方法实例
2018/02/11 Javascript
JavaScript中的E-mail 地址格式验证
2018/03/28 Javascript
vue+eslint+vscode配置教程
2019/08/09 Javascript
Vue快速实现通用表单验证的示例代码
2020/01/09 Javascript
antd-mobile ListView长列表的数据更新遇到的坑
2020/04/08 Javascript
[02:50]2014DOTA2 TI预选赛预选赛 大神专访第一弹!
2014/05/21 DOTA
python实现ping的方法
2015/07/06 Python
python实现爬虫统计学校BBS男女比例(一)
2015/12/31 Python
pandas将DataFrame的列变成行索引的方法
2018/04/10 Python
django重新生成数据库中的某张表方法
2019/08/28 Python
Pandas-Cookbook 时间戳处理方式
2019/12/07 Python
static关键字的用法
2013/10/07 面试题
教师评优事迹材料
2014/01/10 职场文书
入党积极分子学习两会心得体会范文
2014/03/17 职场文书
小学数学教学经验交流材料
2014/05/22 职场文书
博士论文答辩开场白
2015/06/01 职场文书
杨善洲电影观后感
2015/06/04 职场文书
八一建军节主持词
2015/07/01 职场文书
浙江省杭州市平均工资标准是多少?
2019/07/09 职场文书
PHP RabbitMQ消息列队
2022/05/11 PHP
canvas 中如何实现物体的框选
2022/08/05 Javascript