使用PHP的反射Reflection获取对象信息
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就可以了:
1 |
$class = new ReflectionClass( 'Person' ); |
获取属性(Properties):
$properties = $class->getProperties();
foreach($properties as $property) {
echo $property->getName()."n";
}
// 输出:
// _allowDynamicAttributes
// id
// name
// biography
默认情况下,ReflectionClass会获取到所有的属性,private 和 protected的也可以。如果只想获取到private属性,就要额外传个参数:
1 |
$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的反射Reflection获取对象信息的更多相关文章
- mysql数据库连接池使用(三)数据库元数据信息反射数据库获取数据库信息
1.1. mysql数据库连接池使用(三)数据库元数据信息反射数据库获取数据库信息 有时候我们想要获取到数据库的基本信息,当前程序连接的那个数据库,数据库的版本信息,数据库中有哪些表,表中都有什么字段 ...
- 【Python】[面性对象编程] 获取对象信息,实例属性和类属性
获取对象信息1.使用isinstance()判断class类型2.dir() 返回一个对象的所有属性和方法3.如果试图获取不存在的对象会抛出异常[AttributeError]4.正确利用对象内置函数 ...
- python基础——获取对象信息
python基础——获取对象信息 当我们拿到一个对象的引用时,如何知道这个对象是什么类型.有哪些方法呢? 使用type() 首先,我们来判断对象类型,使用type()函数: 基本类型都可以用type( ...
- python 获取对象信息
当我们拿到一个对象的引用时,如何知道这个对象是什么类型.有哪些方法呢? 使用type() 首先,我们来判断对象类型,使用type()函数: 基本类型都可以用type()判断: >>> ...
- python获取对象信息
获取对象信息 拿到一个变量,除了用 isinstance() 判断它是否是某种类型的实例外,还有没有别的方法获取到更多的信息呢? 例如,已有定义: class Person(object): def ...
- Python面向对象 -- 继承和多态、获取对象信息、实例属性和类属性
继承和多态 继承的好处: 1,子类可以使用父类的全部功能 2,多态:当子类和父类都存在相同的方法时,子类的方法会覆盖父类的方法,即调用时会调用子类的方法.这就是继承的另一个好处:多态. 多态: 调用方 ...
- python类的继承和多态,获取对象信息
继承 类的继承机制使得子类可以继承父类中定义的方法,拥有父类的财产,比如有一个Animal的类作为父类,它有一个eat方法: class Animal(object): def __init__(se ...
- python 面向对象编程、获取对象信息
面向对象与面向过程 参考链接:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0 ...
- Python3类和实例之获取对象信息
当我们拿到一个对象的引用时,如何知道这个对象是什么类型,有哪些方法呢 使用type() 判断对象类型使用type()函数 基本类型都可以用type()判断 <class 'int'> &g ...
随机推荐
- 《Java并发编程实战》笔记-状态依赖方法的标准形式
void stateDependentMethod() throws InterruptedException { //必须通过一个锁来保护条件谓词 synchronized(lock) { whil ...
- 将 GitHub 的某人的特定仓库复制到自己的账户下 的方法
访问仓库页面,点击 Fork 按钮创建自己的仓库 Fork 就是将 GitHub 的某个特定仓库复制到自己的账户下. Fork 出的仓库与原仓库是两个不同的仓库,开发者可以随意编辑. 新建的仓库名为& ...
- [转][C#]拆分参数对
本文来自:https://www.jb51.net/article/62932.htm /// <summary> /// 分析 url 字符串中的参数信息 /// </summar ...
- OpenStack单节点制作镜像
1.创建快照 已修改后的时刻为记录,进行制作镜像,选择要制作镜像的虚拟机,点击创建快照,在所弹出的对话框中输入所创建的镜像名称 生成了一个镜像,类型为Snapshot 2.保存镜像 查看镜像列表 [r ...
- ORM多表操作之创建关联表及添加表记录
创建关联表 关于表关系的几个结论 (1)一旦确立表关系是一对多:建立一对多关系----在多对应的表中创建关联字段. (2)一旦确立表关系是多对多:建立多对多关系----创建第三张关系表----id和两 ...
- [UE4]不精准射击 Random Unit Vector in Cone in Radians
- 知识点:Mysql 基本用法之事务
事务 事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性. 事务实例: create table user( id int primar ...
- Linux下安装与卸载anaconda
安装:到安装文件夹的目录下输入 bash Anaconda3-4.1.1-Linux-x86_64.sh 卸载:输入
- 02-zip文件打包
package com.day1; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStre ...
- spark2.3.0 配置spark sql 操作hive
spark可以通过读取hive的元数据来兼容hive,读取hive的表数据,然后在spark引擎中进行sql统计分析,从而,通过spark sql与hive结合实现数据分析将成为一种最佳实践.配置步骤 ...