实例介绍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+MySQL的聊天室设计
Oct 09 PHP
一些常用的php函数
Dec 06 PHP
php 前一天或后一天的日期
Jun 28 PHP
php中http_build_query 的一个问题
Mar 25 PHP
浅谈ThinkPHP的URL重写
Nov 25 PHP
php对二维数组进行相关操作(排序、转换、去空白等)
Nov 04 PHP
PHP微信开发之模板消息回复
Jun 24 PHP
php中10个不同等级压缩优化图片操作示例
Nov 14 PHP
php 微信开发获取用户信息如何实现
Dec 13 PHP
PHP中使用jQuery+Ajax实现分页查询多功能操作(示例讲解)
Sep 17 PHP
PHP删除字符串中非字母数字字符方法总结
Jan 20 PHP
laravel框架中视图的基本使用方法分析
Nov 23 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输出XML到页面的3种方法详解
2013/06/06 PHP
php微信公众号开发之简答题
2018/10/20 PHP
javascript showModalDialog 多层模态窗口实现页面提交及刷新的代码
2009/11/28 Javascript
jQuery源码分析之jQuery中的循环技巧详解
2014/09/06 Javascript
JS仿iGoogle自定义首页模块拖拽特效的方法
2015/02/13 Javascript
javascript实现别踩白块儿小游戏程序
2015/11/22 Javascript
分享两款带遮罩的jQuery弹出框
2015/12/30 Javascript
jQuery Dialog对话框事件用法实例分析
2016/05/10 Javascript
简单掌握JavaScript中const声明常量与变量的用法
2016/05/21 Javascript
深入浅析knockout源码分析之订阅
2016/07/12 Javascript
Vuejs第七篇之Vuejs过渡动画案例全面解析
2016/09/05 Javascript
vue实现列表的添加点击
2016/12/29 Javascript
nodejs 图解express+supervisor+ejs的用法(推荐)
2017/09/08 NodeJs
AngularJS实现controller控制器间共享数据的方法示例
2017/10/30 Javascript
微信小程序实现简易table表格
2020/06/19 Javascript
浅谈javascript事件环微任务和宏任务队列原理
2020/09/12 Javascript
[09:31]2016国际邀请赛中国区预选赛Yao赛后采访 答题送礼
2016/06/27 DOTA
python笔记(2)
2012/10/24 Python
python编写暴力破解zip文档程序的实例讲解
2018/04/24 Python
django中静态文件配置static的方法
2018/05/20 Python
python中的json总结
2018/10/11 Python
python requests证书问题解决
2019/09/05 Python
Python面向对象程序设计之类和对象、实例变量、类变量用法分析
2020/03/23 Python
jupyter lab的目录调整及设置默认浏览器为chrome的方法
2020/04/10 Python
Python实现汇率转换操作
2020/05/03 Python
将pymysql获取到的数据类型是tuple转化为pandas方式
2020/05/15 Python
纯CSS3实现鼠标滑过按钮动画第二节
2020/07/16 HTML / CSS
美国女性服饰销售网站:Nasty Gal(坏女孩)
2016/07/26 全球购物
英国鞋类及配饰零售商:Kurt Geiger
2017/02/04 全球购物
LEGO玩具英国官方商店:LEGO Shop GB
2018/03/27 全球购物
Nike意大利官网:Nike.com IT
2020/01/19 全球购物
《云房子》教学反思
2014/04/20 职场文书
道德之星事迹材料
2014/05/03 职场文书
《藏戏》教学反思
2016/02/23 职场文书
基于Redis实现分布式锁的方法(lua脚本版)
2021/05/12 Redis
Vue鼠标滚轮滚动切换路由效果的实现方法
2021/08/04 Vue.js