zoukankan      html  css  js  c++  java
  • PHP的Reflection反射机制

    原文地址: http://www.nowamagic.net/php/php_Reflection.php

    PHP5添加了一项新的功能:Reflection。这个功能使得程序员可以

    reverse-engineer[逆向工程] class, interface,function,method and extension[扩展库支持]。

    通过PHP代码,就可以得到某object的所有信息,并且可以和它交互。

    如假设以下Person类:

    复制代码
     1 class Person {
     2     /**
     3      * For the sake of demonstration, we"re setting this private
     4      */
     5     private $_allowDynamicAttributes = false;
     6     
     7     /**
     8      * type=primary_autoincrement
     9      */
    10     protected $id = 0;
    11     
    12     /**
    13      * type=varchar length=255 null
    14      */
    15     protected $name;
    16     
    17     /**
    18      * type=text null
    19      */
    20     protected $biography;
    21     public function getId() {
    22         return $this->id;
    23     }
    24     public function setId($v) {
    25         $this->id = $v;
    26     }
    27     public function getName() {
    28         return $this->name;
    29     }
    30     public function setName($v) {
    31         $this->name = $v;
    32     }
    33     public function getBiography() {
    34         return $this->biography;
    35     }
    36     public function setBiography($v) {
    37         $this->biography = $v;
    38     }
    39 }
    复制代码

    通过ReflectionClass,我们可以得到Person类的以下信息:

    • 常量 Contants
    • 属性 Property Names
    • 方法 Method Names
    • 静态属性 Static Properties
    • 命名空间 Namespace
    • Person类是否为final或者abstract

    只要把类名"Person"传递给ReflectionClass就可以了:

    1 $class = new ReflectionClass('Person');

    * 获取属性(Properties):

    复制代码
    1 $properties = $class->getProperties();
    2 foreach($properties as $property) {
    3     echo $property->getName()."
    ";
    4 }
    5 // 输出:
    6 // _allowDynamicAttributes
    7 // id
    8 // name
    9 // 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的注释。

    复制代码
     1 foreach($properties as $property) {
     2     if($property->isProtected()) {
     3         $docblock = $property->getDocComment();
     4         preg_match('/ type=([a-z_]*) /', $property->getDocComment(), $matches);
     5         echo $matches[1]."
    ";
     6     }
     7 }
     8 // Output:
     9 // primary_autoincrement
    10 // varchar
    11 // 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.
    ";
        } else {
            echo "Getter and Setter does not modify the data.
    ";
       }
    }
    复制代码

     

  • 相关阅读:
    Caused by: java.lang.UnsatisfiedLinkError: Couldn't load 。。。。
    final,finally,finalize
    Java位运算总结:位运算用途广泛《转》
    Ext.Ajax.request同步请求
    xstream 别名的用法<转>
    MySQL 获得当前日期时间(以及时间的转换)
    关于用xercesImpl包解析xml文件遇中文报错问题
    kafka java示例
    varnish、squid、apache、nginx缓存的对比<转>
    websphere性能设置和日常维护
  • 原文地址:https://www.cnblogs.com/liuxiaowei/p/7163541.html
Copyright © 2011-2022 走看看