PHP的反射类ReflectionClass、ReflectionMethod使用实例


Posted in PHP onAugust 05, 2014

PHP5 具有完整的反射API,添加对类、接口、函数、方法和扩展进行反向工程的能力。

反射是什么?

它是指在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类、方法、属性、参数等的详细信息,包括注释。这种动态获取的信息以及动态调用对象的方法的功能称为反射API。反射是操纵面向对象范型中元模型的API,其功能十分强大,可帮助我们构建复杂,可扩展的应用。

其用途如:自动加载插件,自动生成文档,甚至可用来扩充PHP语言。

PHP反射api由若干类组成,可帮助我们用来访问程序的元数据或者同相关的注释交互。借助反射我们可以获取诸如类实现了那些方法,创建一个类的实例(不同于用new创建),调用一个方法(也不同于常规调用),传递参数,动态调用类的静态方法。
反射api是PHP内建的OOP技术扩展,包括一些类,异常和接口,综合使用他们可用来帮助我们分析其它类,接口,方法,属性,方法和扩展。这些OOP扩展被称为反射。

平常我们用的比较多的是 ReflectionClass类 和 ReflectionMethod类,例如:

<?php

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
7.Person类是否有某个方法

接下来反射它,只要把类名"Person"传递给ReflectionClass就可以了:

$class = new ReflectionClass('Person'); // 建立 Person这个类的反射类  

$instance  = $class->newInstanceArgs($args); // 相当于实例化Person 类 

1)获取属性(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

通过$property->getName()可以得到属性名。

2)获取注释:

通过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

3)获取类的方法

getMethods()       来获取到类的所有methods。

hasMethod(string)  是否存在某个方法

getMethod(string)  获取方法

4)执行类的方法:

$instance->getName(); // 执行Person 里的方法getName

// 或者:

$method = $class->getmethod('getName'); // 获取Person 类中的getName方法

$method->invoke($instance);    // 执行getName 方法

// 或者:

$method = $class->getmethod('setName'); // 获取Person 类中的setName方法

$method->invokeArgs($instance, array('snsgou.com'));

二、通过ReflectionMethod,我们可以得到Person类的某个方法的信息:

1.是否“public”、“protected”、“private” 、“static”类型
2.方法的参数列表
3.方法的参数个数
4.反调用类的方法

// 执行detail方法

$method = new ReflectionMethod('Person', 'test');
if ($method->isPublic() && !$method->isStatic()) {

 echo 'Action is right';

}

echo $method->getNumberOfParameters(); // 参数个数

echo $method->getParameters(); // 参数对象数组
PHP 相关文章推荐
国内php原创论坛
Oct 09 PHP
MySQL中create table语句的基本语法是
Jan 15 PHP
php md5下16位和32位的实现代码
Apr 09 PHP
PHP 类相关函数的使用详解
May 10 PHP
PHP开发微信支付的代码分享
May 25 PHP
PHP中通过trigger_error触发PHP错误示例
Jun 23 PHP
实例简介PHP的一些高级面向对象编程的特性
Nov 27 PHP
PHP通过微信跳转的Code参数获取用户的openid(关键代码)
Jul 06 PHP
PHP使用PHPExcel删除Excel单元格指定列的方法
Jul 06 PHP
ThinkPHP实现分页功能
Apr 28 PHP
php获取是星期几的的一些常用姿势
Dec 15 PHP
PHP中isset、empty的用法与区别示例详解
Nov 05 PHP
实例介绍PHP的Reflection反射机制
Aug 05 #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
You might like
PHP函数篇之掌握ord()与chr()函数应用
2011/12/05 PHP
让CodeIgniter数据库缓存自动过期的处理的方法
2014/06/12 PHP
JavaScript实现向OL列表内动态添加LI元素的方法
2015/03/21 Javascript
AspNet中使用JQuery boxy插件的确认框
2015/05/20 Javascript
jQuery实现网站添加高亮突出显示效果的方法
2015/06/26 Javascript
详解JavaScript对象序列化
2016/01/19 Javascript
AngularJS基于ngInfiniteScroll实现下拉滚动加载的方法
2016/12/14 Javascript
利用JavaScript实现栈的数据结构示例代码
2017/08/02 Javascript
微信小程序之swiper滑动面板用法示例
2018/12/04 Javascript
配置一个vue3.0项目的完整步骤
2019/04/26 Javascript
了解JavaScript表单操作和表单域
2019/05/27 Javascript
js类的继承定义与用法分析
2019/06/21 Javascript
JavaScript解析JSON数据示例
2019/07/16 Javascript
webpack是如何实现模块化加载的方法
2019/11/06 Javascript
vue 实现移动端键盘搜索事件监听
2019/11/06 Javascript
js+canvas实现图片格式webp/png/jpeg在线转换
2020/08/22 Javascript
Vue Elenent实现表格相同数据列合并
2020/11/30 Vue.js
layui使用及简单的三级联动实现教程
2020/12/01 Javascript
node脚手架搭建服务器实现token验证的方法
2021/01/20 Javascript
[03:06]V社市场总监Dota2项目负责人Erik专访:希望更多中国玩家加入DOTA2
2014/07/11 DOTA
[38:40]2018DOTA2亚洲邀请赛 4.6淘汰赛 mineski vs LGD 第一场
2018/04/10 DOTA
使用pandas中的DataFrame数据绘制柱状图的方法
2018/04/10 Python
django 实现celery动态设置周期任务执行时间
2019/11/19 Python
Python如何在DataFrame增加数值
2020/02/14 Python
纯CSS3实现表单验证效果(非常不错)
2017/01/18 HTML / CSS
中英双版中文教师求职信
2013/10/27 职场文书
《小熊住山洞》教学反思
2014/02/21 职场文书
优秀少先队辅导员先进事迹材料
2014/05/18 职场文书
中小学校园安全广播稿
2014/09/29 职场文书
2014年班务工作总结
2014/12/02 职场文书
帝企鹅日记观后感
2015/06/10 职场文书
2016新党章学习心得体会
2016/01/15 职场文书
python3读取文件指定行的三种方法
2021/05/24 Python
浅谈MySQL user权限表
2021/06/18 MySQL
微信小程序scroll-view不能左右滑动问题的解决方法
2021/07/09 Javascript
Ruby使用Mysql2连接操作MySQL
2022/04/19 Ruby