PHP的Reflection反射机制
原文地址: http://www.nowamagic.net/php/php_Reflection.php
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类的以下信息:
- 常量 Contants
- 属性 Property Names
- 方法 Method Names
- 静态属性 Static Properties
- 命名空间 Namespace
- 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_PRIVATE
通过$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对象的数组。
不再演示。
赋一个利用反射加载类实例的工具类写法:
<?php
/**
* Desc: 反射加载类
* Class: ClassLoader
* Package: App\Lib
* User: zb
* Date: 2019/5/22 15:21
*/ namespace App\Lib; class ClassLoader
{
private static $obj = []; /**
* 上传类map
*/
private static function uploadClassMap ()
{
$map = [
'image' => 'App\Lib\Upload\Image',//key为传递参数key
'video' => 'App\Lib\Upload\Video',
];
return $map;
} /**
* model类map
*/
private static function modelClassMap ()
{
$map = [
'video' => 'App\Model\Video',
];
return $map;
} /**
* aliyun类map
*/
private static function aliyunClassMap ()
{
$map = [
'vod' => 'App\Lib\Aliyun\AliyunVod',
];
return $map;
} /**
* cache类map
*/
private static function cacheClassMap ()
{
$map = [
'video' => 'App\Lib\Cache\Video',
];
return $map;
} /**
* 类实例map指南
* @param string $guideKey 指南key
* @param string $classKey classKey
* @return array|bool
*/
private static function guideClassMap (string $guideKey, string $classKey)
{
$guideKey = strtolower($guideKey);
$guideMap = [
'upload' => self::uploadClassMap(),
'model' => self::modelClassMap(),
'aliyun' => self::aliyunClassMap(),
'cache' => self::cacheClassMap(),
];
return isset($guideMap[$guideKey][$classKey]) ? $guideMap[$guideKey][$classKey] : array();
} /**
* @param string $guideKey guideKey
* @param string $classKey classKey键
* @param array $params 构造函数参数
* @param bool $instance 是否需要实例化
* @return object|string 返回obj或字符串
* @throws \ReflectionException
*/
public static function initClass (string $guideKey, string $classKey, $params = [], $instance = true)
{
if (!$params && isset(self::$obj[$guideKey . '-' . $classKey]) && is_object(self::$obj[$guideKey . '-' . $classKey])) {
return self::$obj[$guideKey . '-' . $classKey];
} else {
unset(self::$obj[$guideKey . '-' . $classKey]);
} if (!self::guideClassMap($guideKey, $classKey)) {
throw new \ReflectionException('加载类不存在');
}
$class = self::guideClassMap($guideKey, $classKey);
try {
$obj = $instance ? (new \ReflectionClass($class))->newInstanceArgs($params) : $class;
if (!$params) {
self::$obj[$guideKey . '-' . $classKey] = $obj;
}
return $obj;
} catch (\ReflectionException $e) {
throw new \ReflectionException('类加载失败');
}
} }
PHP的Reflection反射机制的更多相关文章
- Java进阶之reflection(反射机制)——反射概念与基础
反射机制是Java动态性之一,而说到动态性首先得了解动态语言.那么何为动态语言? 一.动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化.比如常见 ...
- java学习--Reflection反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制. ...
- Java之reflection(反射机制)——通过反射操作泛型,注解
一.反射操作泛型(Generic) Java采用泛型擦除机制来引入泛型.Java中的泛型仅仅是给编译器Javac使用的,确保数据的安全性和免去强制类型转换的麻烦.但是编译一旦完成,所有和泛型有关的类型 ...
- C# Reflection反射机制
一.反射 什么是反射 .Net的应用程序由几个部分:'程序集(Assembly)'.'模块(Module)'.'类型(class)'组成: 反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组 ...
- Java的反射机制(Reflection)
反射机制 指可以在运动时加载.探知.使用编译期间完全未知的类 程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个已加载的类,都能够获取这个类的属性和方法:对于任意一个对象可以调用它的任意一个 ...
- Java反射机制(Reflection)
Java反射机制(Reflection) 一.反射机制是什么 Java反射机制是程序在运行过程中,对于任意一个类都能够知道这个类的所有属性和方法;对于任意一个对象都能够调用它的任意一个方法和属性,这种 ...
- Java - 反射机制(Reflection)
Java - 反射机制(Reflection) > Reflection 是被视为 动态语言的关键,反射机制允许程序在执行期借助于 Reflection API 取得任何类的 ...
- 反射机制(reflection)动态相关机制
功能:动态获取类的信息以及动态调用对象的方法. Java反射机制主要提供了以下功能: 1.在运行时判断任意一个对象所属的类. 2.在运行时构造任意一个类的对象. 3.在运行时判断任意一个类所具有的成员 ...
- java反射机制--reflection
反射,reflection,听其名就像照镜子一样,可以看见自己也可以看见别人的每一部分.在java语言中这是一个很重要的特性.下面是来自sun公司官网关于反射的介绍: Reflection is ...
随机推荐
- Ubuntu16.04安装jupiter
Ubuntu16.04安装jupiter 1.安装pip pip是一个安装和管理 Python 包的工具, 是 easy_install 的一个替换品.自然对应Python3,则有pip3. Pyth ...
- python中函数重载和重写
python 中的重载 在python中,具有重载的思想却没有重载的概念.所以有的人说python这么语言并不支持函数重载,有的人说python具有重载功能.实际上python编程中具有重载的目的缺 ...
- [AMPPZ2014]Petrol
关键点的最小生成树? 关键点初始化为0,跑多源最短路,然后重构整个图,用Kruskal跑最小生成树 然后跑树链剖分在线回答询问 对树上每个点维护到链顶的最大值,结合线段树可以做到\(\Theta(n ...
- for、for..in、forEach、$.each等循环性能测试
var num = 10000000,arr = []; for(i=0;i<num;i++){ arr[i] = i+2; } //1) 使用 for 循环 function test1() ...
- hallo world
- vmware下载存储vmdk文件后缀变-flat处理方式
将vmware存储中的虚拟机vmdk文件下载到本地,下载完成后,下载了2个vmdk文件 一份为:xx.vmdk (通常1KB左右) 一份为:xx-flat.vmdk (此为源文件正常大小) ...
- Jquery插件网站持续添加。。。
Look Fro Less,Do More www.jq22.com
- CSS选择器之伪类选择器(伪元素)
selection [CSS4]应用于文档中被用户高亮的部分(比如使用鼠标或其他选择设备选中的部分).(IE8及以下不支持)(火狐-moz-selection) first-line 选择每个 < ...
- 【node】node的核心模块---http模块,http的服务器和客户端
nodejs事件机制 ##### http服务器和客户端 node.js标准库提供了http模块,其中封装了一个高效的http服务器和一个简易的http客户端 HTTP服务器 1. http.crea ...
- Play-with-chrome之环境搭建
前言 浏览器漏洞在 APT 攻击中用的比较多,而且这基本上是用户上网的标配了,所以研究浏览器的漏洞是十分有前景的,我认为.我选择 chrome 浏览器 ( chromium和 chrome之间的关系请 ...