PHP反射机制Reflection

发布于:2020-03-20 22:14:03

反射机制简介

在面向对象编程中,对象被系统赋予了自省的能力,而实现这个自省的过程就是反射。

反射,简单理解就是根据目标物,得到目标物所携带的属性、技能等。在PHP中,我们可以通过反射对象,提取关于类、方法、属性、参数、注释等的详细信息。这种动态获取信息以及动态调用对象方法的功能称为反射API。

反射是操纵面向对象范型中元模型的API,其功能十分强大,可帮助我们构建复杂,可扩展的应用。比如:自动加载插件,自动生成文档,甚至可用来扩充PHP语言。

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

  1. 常量 Contants

  2. 属性 Property

  3. 方法 Method

  4. 属性 Static Properties

  5. 命名空间 Namespace

  6. 类的修饰,是否为final或者abstract

使用

假设我们现在有一个这样的类:

class Student{    public $name;    protected $age;    private $sex;    public function __construct($name, $age, $sex)
    {        $this->setName($name);        $this->setAge($age);        $this->setSex($sex);
    }    public function setName($name)
    {        $this->name = $name;
    }    protected function setAge($age)
    {        $this->age = $age;
    }    private function setSex($sex)
    {        $this->sex = $sex;
    }
}

调用反射导出接口:

\ReflectionClass::export(Student::class);

导出结果:

/**
 * User: woodylan
 * Date: 2019/3/11
 * Time: 21:59
 */Class [ <user> class Student ] {
  @@ /path/reflection.php 8-35

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [3] {
    Property [ <default> public $name ]
    Property [ <default> protected $age ]
    Property [ <default> private $sex ]
  }

  - Methods [4] {
    Method [ <user, ctor> public method __construct ] {
      @@ /path/reflection.php 14 - 19

      - Parameters [3] {
        Parameter #0 [ <required> $name ]
        Parameter #1 [ <required> $age ]
        Parameter #2 [ <required> $sex ]
      }
    }

    Method [ <user> public method setName ] {
      @@ /path/reflection.php 21 - 24

      - Parameters [1] {
        Parameter #0 [ <required> $name ]
      }
    }

    Method [ <user> protected method setAge ] {
      @@ /path/reflection.php 26 - 29

      - Parameters [1] {
        Parameter #0 [ <required> $age ]
      }
    }

    Method [ <user> private method setSex ] {
      @@ /path/reflection.php 31 - 34

      - Parameters [1] {
        Parameter #0 [ <required> $sex ]
      }
    }
  }
}

获取对象属性列表

$student = new Student('woodylan', 18, 1);
$reflect = new ReflectionObject($student);
$props = $reflect->getProperties();foreach ($props as $prop) {    print $prop->getName() . "\n";
}

输出:

nameage
sex

获取对象方法列表

$methods = $reflect->getMethods();foreach ($methods as $prop) {    print $prop->getName() . "\n";
}

输出:

__constructsetName
setAge
setSex

反射获取类的原型

$reflection = new ReflectionClass(Student::class);
$className = $reflection->getName();
$methods = [];
$properties = [];foreach ($reflection->getProperties() as $value) {
    $properties[$value->getName()] = $value;
}foreach ($reflection->getMethods() as $value) {
    $methods[$value->getName()] = $value;
}echo "class {$className}\n{\n";
is_array($properties) && ksort($properties);foreach ($properties as $key => $value) {    echo "\t";    echo $value->isPublic() ? ' public' : '', $value->isPrivate() ? ' private' : '',
    $value->isProtected() ? ' protected' : '',
    $value->isStatic() ? ' static' : '';    echo "\t{$key}\n";
}echo "\n";if (is_array($methods)) ksort($methods);foreach ($methods as $key => $value) {    echo "\tfunction {$key}(){}\n";
}echo "}\n";

输出:

class Student{	protected   age	public		name	private     sex	function __construct(){}	function setAge(){}	function setName(){}	function setSex(){}
}

其它API

反射不仅可以用于类和对象,还可以用于函数、扩展模块、异常等,官方提供了一系列的API方法,以下列举部分。

文档地址:http://php.net/manual/zh/book.reflection.php


    阅读 415+

    一片空白

    父爱如山,不善表达。回想十多年前,总记得父亲有个宽厚的肩膀,小小的自己跨坐在上面,越过人山人海去看更广阔的天空,那个时候期望自己有一双翅膀,能够像鸟儿一样飞得高,看得远。虽然父亲有时会和自己开玩笑,但在做错事的时候会受到严厉的训斥。父亲有双粗糙的大手掌。