实例介绍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学习教程之第2天
Jun 15 PHP
php MYSQL 数据备份类
Jun 19 PHP
php弹出对话框实现重定向代码
Jan 23 PHP
destoon实现公司新闻详细页添加评论功能的方法
Jul 15 PHP
php给图片添加文字水印方法汇总
Aug 27 PHP
Apache启动报错No space left on device: AH00023该怎么解决
Oct 16 PHP
CI框架数据库查询缓存优化的方法
Nov 21 PHP
PHP判断数组是否为空的常用方法(五种方法)
Feb 08 PHP
php安全配置记录和常见错误梳理(总结)
Mar 28 PHP
浅谈PHP封装CURL
Mar 06 PHP
PHP面向对象程序设计之对象的遍历操作示例
Jun 12 PHP
关于laravel 子查询 & join的使用
Oct 16 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处理Oracle的CLOB实例
2014/11/03 PHP
thinkphp隐藏index.php/home并允许访问其他模块的实现方法
2016/10/13 PHP
PHP多个图片压缩成ZIP的方法
2020/08/18 PHP
PHP实现一个轻量级容器的方法
2019/01/28 PHP
Javascript Global对象
2009/08/13 Javascript
我遇到的参数传递中 双引号单引号嵌套问题
2010/02/11 Javascript
JQuery将文本转化成JSON对象需要注意的问题
2011/05/09 Javascript
浅析jquery ajax异步调用方法中不能给全局变量赋值的原因及解决方法
2014/01/10 Javascript
vue.js开发环境搭建教程
2017/05/04 Javascript
自定义事件解决重复请求BUG的问题
2017/07/11 Javascript
vue动画之点击按钮往上渐渐显示出来的实例
2018/09/29 Javascript
Vue的Eslint配置文件eslintrc.js说明与规则介绍
2020/02/03 Javascript
[48:47]VGJ.S vs NB 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
[53:10]完美世界DOTA2联赛决赛日 FTD vs GXR 第二场 11.08
2020/11/11 DOTA
使用Python对MySQL数据操作
2017/04/06 Python
Python文件操作之合并文本文件内容示例代码
2017/09/19 Python
将字典转换为DataFrame并进行频次统计的方法
2018/04/08 Python
只需7行Python代码玩转微信自动聊天
2019/01/27 Python
2019 Python最新面试题及答案16道题
2019/04/11 Python
Python Django框架实现应用添加logging日志操作示例
2019/05/17 Python
python3.6环境安装+pip环境配置教程图文详解
2019/06/20 Python
Django RBAC权限管理设计过程详解
2019/08/06 Python
基于python实现雪花算法过程详解
2019/11/16 Python
Django如何重置migration的几种情景
2021/02/24 Python
资深生产主管自我评价
2013/09/22 职场文书
中级会计职业生涯规划范文
2014/01/16 职场文书
安全生产实施方案
2014/02/23 职场文书
爽歪歪广告词
2014/03/20 职场文书
好听的队名和口号
2014/06/09 职场文书
新闻稿怎么写
2015/07/18 职场文书
国庆节主题班会
2015/08/15 职场文书
2019关于垃圾分类处理的调查报告
2019/12/26 职场文书
Python实战之疫苗研发情况可视化
2021/05/18 Python
Vue + iView实现Excel上传功能的完整代码
2021/06/22 Vue.js
Pillow图像处理库安装及使用
2022/04/12 Python
Python中的 No Module named ***问题及解决
2022/07/23 Python