实例介绍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)
Oct 09 PHP
php 数据库字段复用的基本原理与示例
Jul 22 PHP
使用JSON实现数据的跨域传输的php代码
Dec 20 PHP
怎么在Windows系统中搭建php环境
Aug 31 PHP
php数组去重实例及分析
Nov 26 PHP
php防止站外远程提交表单的方法
Oct 20 PHP
PHP多线程类及用法实例
Dec 03 PHP
PHP获取当前相对于域名目录的方法
Jun 26 PHP
浅谈php处理后端&接口访问超时的解决方法
Oct 29 PHP
PHP异步进程助手async-helper
Feb 05 PHP
PHP设计模式之原型设计模式原理与用法分析
Apr 25 PHP
thinkphp5框架实现的自定义扩展类操作示例
May 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可逆加密函数(分享)
2013/06/06 PHP
php图片的二进制转换实现方法
2014/12/15 PHP
修复ShopNC使用QQ 互联时提示100010 错误
2015/11/08 PHP
JS中的public和private对象,即static修饰符
2012/01/18 Javascript
jquery放大镜效果超漂亮噢
2013/11/15 Javascript
当滚动条滚动到页面底部自动加载增加内容的js代码
2014/05/13 Javascript
jQuery的context属性用法实例
2014/12/27 Javascript
详细分析使用AngularJS编程中提交表单的方式
2015/06/19 Javascript
js中 javascript:void(0) 用法详解
2015/08/11 Javascript
jQuery鼠标经过方形图片切换成圆边效果代码分享
2015/08/20 Javascript
详解js中的apply与call的用法
2016/07/30 Javascript
全面解析Angular中$Apply()及$Digest()的区别
2016/08/04 Javascript
JavaScript排序算法动画演示效果的实现方法
2016/10/18 Javascript
AngularJS的依赖注入实例分析(使用module和injector)
2017/01/19 Javascript
vue中父子组件注意事项,传值及slot应用技巧
2018/05/09 Javascript
使用webpack搭建react开发环境的方法
2018/05/15 Javascript
Vue验证码60秒倒计时功能简单实例代码
2018/06/22 Javascript
js与jQuery实现获取table中的数据并拼成json字符串操作示例
2018/07/12 jQuery
微信小程序实现滴滴导航tab切换效果
2018/07/24 Javascript
JS实现可视化音频效果的实例代码
2020/01/16 Javascript
JS实现炫酷轮播图
2020/11/15 Javascript
Python选课系统开发程序
2016/09/02 Python
深入理解Python对Json的解析
2017/02/14 Python
Python变量和数据类型详解
2017/02/15 Python
Python开发入门——迭代的基本使用
2020/09/03 Python
Opencv 图片的OCR识别的实战示例
2021/03/02 Python
使用CSS3编写灰阶滤镜来制作黑白照片效果的方法
2016/05/09 HTML / CSS
比利时的在线灯具店:Lampen24.be
2019/07/01 全球购物
党支部创先争优公开承诺书
2015/04/30 职场文书
道歉的话怎么说
2015/05/12 职场文书
2015年工商所工作总结
2015/05/21 职场文书
我爱我班主题班会
2015/08/13 职场文书
文书工作总结(范文)
2019/07/11 职场文书
详解MySQL 用户权限管理
2021/04/20 MySQL
Python Pandas pandas.read_sql函数实例用法
2021/06/21 Python
golang中字符串MD5生成方式总结
2021/07/04 Golang