实例介绍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 相关文章推荐
第二节 对象模型 [2]
Oct 09 PHP
FCKeditor的安装(PHP)
Jan 13 PHP
PHP设计模式 注册表模式(多个类的注册)
Feb 05 PHP
通过php快速统计某个数据库中每张表的数据量
Sep 04 PHP
PHP系统命令函数使用分析
Jul 05 PHP
PHP实现对文本数据库的常用操作方法实例演示
Jul 04 PHP
php实现图片添加描边字和马赛克的方法
Dec 10 PHP
php判断两个日期之间相差多少个月份的方法
Jun 18 PHP
PHP中filter函数校验数据的方法详解
Jul 31 PHP
Apache启动报错No space left on device: AH00023该怎么解决
Oct 16 PHP
解决PHP上传非标准格式的图片pjpeg失败的方法
Mar 12 PHP
Laravel框架实现简单的学生信息管理平台案例
May 07 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
Protoss兵种介绍
2020/03/14 星际争霸
最贵的咖啡是怎么产生的,它的风味怎么样?
2021/03/04 新手入门
xml+php动态载入与分页
2006/10/09 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(九)
2014/06/24 PHP
PHP中exec函数和shell_exec函数的区别
2014/08/20 PHP
laravel框架使用阿里云短信发送消息操作示例
2020/02/15 PHP
js 对象是否存在判断
2009/07/15 Javascript
JS图片切换的具体方法(带缩略图版)
2013/11/12 Javascript
WEB前端设计师常用工具集锦
2014/12/09 Javascript
Javascript中的匿名函数与封装介绍
2015/03/15 Javascript
JavaScript使用指针操作实现约瑟夫问题实例
2015/04/07 Javascript
javascript中mouseover、mouseout使用详解
2015/07/19 Javascript
jQuery可见性过滤选择器用法示例
2016/09/09 Javascript
jquery-mobile基础属性与用法详解
2016/11/23 Javascript
JS实现调用本地摄像头功能示例
2018/05/18 Javascript
vue移动端实现红包雨效果
2020/06/23 Javascript
使用jQuery给Table动态增加行、清空table的方法
2018/09/05 jQuery
Vue实现表格批量审核功能实例代码
2019/05/28 Javascript
JS 自执行函数原理及用法
2019/08/05 Javascript
浅谈JavaScript中this的指向问题
2020/07/28 Javascript
nuxt 自定义 auth 中间件实现令牌的持久化操作
2020/11/05 Javascript
[02:12]探秘2016国际邀请赛中国区预选赛选手房间
2016/06/25 DOTA
[01:14:30]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第二场 8.20.mp4
2019/08/22 DOTA
最大K个数问题的Python版解法总结
2016/06/16 Python
Python实现发送QQ邮件的封装
2017/07/14 Python
Django管理员账号和密码忘记的完美解决方法
2018/12/06 Python
Python基础学习之基本数据结构详解【数字、字符串、列表、元组、集合、字典】
2019/06/18 Python
解决python虚拟环境切换无效的问题
2020/04/30 Python
css3动画效果小结(推荐)
2016/07/25 HTML / CSS
CHARLES & KEITH加拿大官网:新加坡时尚品牌
2020/03/26 全球购物
教师简历自我评价
2014/02/03 职场文书
企业仓管员岗位职责
2014/06/15 职场文书
审计局2014法制宣传日活动总结
2014/11/01 职场文书
自主招生自荐信格式
2015/03/04 职场文书
导游词之西安大清真寺
2019/12/17 职场文书
浅谈Redis主从复制以及主从复制原理
2021/05/29 Redis