实例介绍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中文汉字验证码
Apr 08 PHP
如何使用php输出时间格式
Aug 31 PHP
thinkphp普通查询与表达式查询实例分析
Nov 24 PHP
推荐5款跨平台的PHP编辑器
Dec 25 PHP
php自动获取关键字的方法
Jan 06 PHP
PHP多线程之内部多线程实例分析
Mar 09 PHP
php用正则判断是否为数字的方法
Mar 25 PHP
浅析Yii2缓存的使用
May 10 PHP
centos7上编译安装php7以php-fpm方式连接apache
Nov 08 PHP
浅析PHP 中move_uploaded_file 上传中文文件名失败
Apr 17 PHP
详解使用php-cs-fixer格式化代码
Sep 16 PHP
PHP实现rar解压读取扩展包小结
Jun 03 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(8) php 数组
2010/03/05 PHP
Yii2.0中使用js异步删除示例
2017/03/10 PHP
全面解析PHP面向对象的三大特征
2017/06/10 PHP
PHP实现类似题库抽题效果
2018/08/16 PHP
php+js实现点赞功能的示例详解
2020/08/07 PHP
Extjs学习笔记之三 extjs form更多的表单项
2010/01/07 Javascript
基于jQuery的计算文本框字数的代码
2012/06/06 Javascript
JSON辅助格式化处理方法
2013/03/26 Javascript
javascript Array.prototype.slice的使用示例
2013/11/14 Javascript
jQuery实现的多选框多级联动插件
2014/05/02 Javascript
javascript实现的HashMap类代码
2014/06/27 Javascript
ECMAScript 6即将带给我们新的数组操作方法前瞻
2015/01/06 Javascript
轻松学习jQuery插件EasyUI EasyUI实现拖放商品放置购物车
2015/11/30 Javascript
JavaScript通过HTML的class来获取HTML元素的方法总结
2016/05/24 Javascript
jQuery图片轮播功能实例代码
2017/01/29 Javascript
jQuery插件FusionCharts实现的2D面积图效果示例【附demo源码下载】
2017/03/06 Javascript
使用jQuery实现动态添加小广告
2017/07/11 jQuery
vue+element的表格实现批量删除功能示例代码
2018/08/17 Javascript
layui获取选中行数据的实例讲解
2018/08/19 Javascript
html+jQuery实现拖动滑块图片拼图验证码插件【移动端适用】
2019/09/10 jQuery
vue改变循环遍历后的数据实例
2019/11/07 Javascript
CKEditor扩展插件:自动排版功能autoformat插件实现方法详解
2020/02/06 Javascript
2020淘宝618理想生活列车自动领喵币js脚本的代码
2020/06/02 Javascript
Python3中的列表生成式、生成器与迭代器实例详解
2018/06/11 Python
python实现简单日志记录库glog的使用
2019/12/13 Python
TensorFlow MNIST手写数据集的实现方法
2020/02/05 Python
Python 实现黑客帝国中的字符雨的示例代码
2020/02/20 Python
python脚本使用阿里云slb对恶意攻击进行封堵的实现
2021/02/04 Python
Shopee菲律宾:在线购买和出售
2019/11/25 全球购物
草莓网中国:StrawberryNet中国
2020/08/17 全球购物
linux面试题参考答案(10)
2013/11/04 面试题
毕业生自我鉴定
2013/11/05 职场文书
大一新生军训时的自我评价分享
2013/12/05 职场文书
高中生活自我鉴定
2014/01/18 职场文书
保送生自荐信范文
2015/03/26 职场文书
九年级语文教学反思
2016/03/03 职场文书