原文地址: 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反射机制的更多相关文章

  1. Java进阶之reflection(反射机制)——反射概念与基础

    反射机制是Java动态性之一,而说到动态性首先得了解动态语言.那么何为动态语言? 一.动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化.比如常见 ...

  2. java学习--Reflection反射机制

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制. ...

  3. Java之reflection(反射机制)——通过反射操作泛型,注解

    一.反射操作泛型(Generic) Java采用泛型擦除机制来引入泛型.Java中的泛型仅仅是给编译器Javac使用的,确保数据的安全性和免去强制类型转换的麻烦.但是编译一旦完成,所有和泛型有关的类型 ...

  4. C# Reflection反射机制

    一.反射 什么是反射 .Net的应用程序由几个部分:'程序集(Assembly)'.'模块(Module)'.'类型(class)'组成: 反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组 ...

  5. Java的反射机制(Reflection)

    反射机制 指可以在运动时加载.探知.使用编译期间完全未知的类 程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个已加载的类,都能够获取这个类的属性和方法:对于任意一个对象可以调用它的任意一个 ...

  6. Java反射机制(Reflection)

    Java反射机制(Reflection) 一.反射机制是什么 Java反射机制是程序在运行过程中,对于任意一个类都能够知道这个类的所有属性和方法;对于任意一个对象都能够调用它的任意一个方法和属性,这种 ...

  7. Java - 反射机制(Reflection)

    Java - 反射机制(Reflection)     > Reflection 是被视为 动态语言的关键,反射机制允许程序在执行期借助于 Reflection API 取得任何类的       ...

  8. 反射机制(reflection)动态相关机制

    功能:动态获取类的信息以及动态调用对象的方法. Java反射机制主要提供了以下功能: 1.在运行时判断任意一个对象所属的类. 2.在运行时构造任意一个类的对象. 3.在运行时判断任意一个类所具有的成员 ...

  9. java反射机制--reflection

    反射,reflection,听其名就像照镜子一样,可以看见自己也可以看见别人的每一部分.在java语言中这是一个很重要的特性.下面是来自sun公司官网关于反射的介绍:    Reflection is ...

随机推荐

  1. 解决win7无法打开chm格式文件的问题

    解决win7无法打开chm格式文件的问题. (一).简单方法(本人用的这个) 1.打开chm2.win7提示安全问题3.chm无法显示内容4.关闭chm5.右键点击chm,点击“解除锁定”,ok  没 ...

  2. overload与override的区别

    override(重写,覆盖) 1.方法名.参数.返回值相同. 2.子类方法不能缩小父类方法的访问权限. 3.子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常). 4.存在于父类和子类之 ...

  3. CSS 几款比较常用的翻转特效

    第一个:360度翻转特效 <style>* { margin:0; padding:0; } .aa { width: 220px; height: 220px; margin: 0 au ...

  4. 格式化字符串漏洞利用实战之 0ctf-easyprintf

    前言 这是 0ctf 的一道比较简单的格式化串的题目. 正文 逻辑非常简单 do_read 可以打印内存地址的数据,可用来 泄露 got. leave 格式化字符串漏洞. printf(s) 直接调用 ...

  5. OneNet平台初探成功

    1.经过半个月的研究,终于成功对接OneNet平台,实现远程控制LED灯的亮灭 2.在调试的过程中也遇到了很多问题,做一下总结 3.硬件:STM32F103C8T6的最小系统板,ESP8266-WiF ...

  6. 线程间的通信方式2--管道流Pipes

    “管道”是java.io包的一部分.它是Java的特性,而不是Android特有的.一条“管道”为两个线程建立一个单向的通道.生产者负责写数据,消费者负责读取数据. 下面是一个使用管道流进行通信的例子 ...

  7. 5maven工程莫名其妙只在项目名称那里有一个红叉

    manven工程里面没有报错的地方,编译也没有问题,只是项目名称那里有一个红叉.   解决办法:   右击项目-->maven-->update project   注意: 这种方法有时可 ...

  8. Pig order by用法举例

    sorted = order data by $0;   数值类型按照数值大小比较 chararray类型按照字符的字典顺序比较 bytearray按照字节的字典顺序比较 复杂类型(map.tuple ...

  9. Asp.net mvc Kendo UI Grid的使用(三)

    上一篇的操作已经能够显示基本数据了,这次介绍一下如何进行数据操作以及显现自定义命令. 第一步当然还是准备数据: [HttpPost] public ActionResult PersonalList_ ...

  10. iframe内联框

    内联框中表格的下划线老是显示不出来,设置宽度百分比不起作用,调整了文本域的宽度也不行.只能动态调整iframe的高度.