实例介绍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 编程安全性小结
Jan 08 PHP
PHP 杂谈《重构-改善既有代码的设计》之三 重新组织数据
Apr 09 PHP
PHP的password_hash()使用实例
Mar 17 PHP
PHP中判断文件存在使用is_file还是file_exists?
Apr 03 PHP
php使用MySQL保存session会话的方法
Jun 18 PHP
php+ajax制作无刷新留言板
Oct 27 PHP
分享PHP计算两个日期相差天数的代码
Dec 23 PHP
Yii隐藏URL中index.php的方法
Jul 12 PHP
详解php中 === 的使用
Oct 24 PHP
PHP获取input输入框中的值去数据库比较显示出来
Nov 16 PHP
CakePHP框架Session设置方法分析
Feb 23 PHP
laravel 数据验证规则详解
Oct 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网页游戏学习之Xnova(ogame)源码解读(八)
2014/06/23 PHP
thinkphp分页集成实例
2017/07/24 PHP
Yii2语言国际化的配置教程
2018/08/19 PHP
Laravel框架学习笔记之批量更新数据功能
2019/05/30 PHP
BOOM vs RR BO5 第一场 2.14
2021/03/10 DOTA
建议大家看下JavaScript重要知识更新
2007/07/08 Javascript
JavaScript 开发中规范性的一点感想
2009/06/23 Javascript
jquery 关于event.target使用的几点说明介绍
2013/04/26 Javascript
一个小例子解释如何来阻止Jquery事件冒泡
2014/07/17 Javascript
PHP+jQuery+Ajax实现多图片上传效果
2015/03/14 Javascript
jQuery数据检索中根据关键字快速定位GridView指定行的实现方法
2016/06/08 Javascript
JavaScript检测原始值、引用值、属性
2016/06/20 Javascript
js模式化窗口问题![window.dialogArguments]
2016/10/30 Javascript
BootStrap select2 动态改变值的方法
2017/02/10 Javascript
js实现HTML中Select二级联动的实例
2018/01/05 Javascript
使用 Vue 绑定单个或多个 Class 名的实例代码
2018/01/08 Javascript
如何用input标签和jquery实现多图片的上传和回显功能
2018/05/16 jQuery
详解Vue Elementui中的Tag与页面其它元素相互交互的两三事
2018/09/25 Javascript
Vue源码中要const _toStr = Object.prototype.toString的原因分析
2018/12/09 Javascript
用js简单提供增删改查接口
2019/05/12 Javascript
node.js express捕获全局异常的三种方法实例分析
2019/12/27 Javascript
VUE页面中通过双击实现复制表格中内容的示例代码
2020/06/11 Javascript
Python多进程同步Lock、Semaphore、Event实例
2014/11/21 Python
Python自动化测试Eclipse+Pydev 搭建开发环境
2016/08/15 Python
遗传算法之Python实现代码
2017/10/10 Python
用tensorflow实现弹性网络回归算法
2018/01/09 Python
Python开发最牛逼的IDE——pycharm
2018/08/01 Python
使用SVG实现提示框功能的示例代码
2020/06/05 HTML / CSS
ALEX AND ANI:手镯,项链,耳环和更多
2017/04/20 全球购物
护理职业应聘自荐书
2013/09/29 职场文书
建筑工程管理专业自荐信范文
2013/12/28 职场文书
土木工程专业推荐信
2014/02/19 职场文书
省级三好学生主要事迹材料
2015/11/03 职场文书
中学语文教学反思
2016/02/16 职场文书
golang 实现对Map进行键值自定义排序
2021/04/28 Golang
详解JS数组方法
2021/11/20 Javascript