PHP反射教程
PHP中的反射API就想JAVA中的java.lang.reflect包一样, 它有一系列可以分析的方法和类置的类组成。 在某些方面和对象函数相似。
入门
反射API不仅仅可以用来检查类, 还可以查看编译到PHP语言中的扩展, 部分5如下所示:
类 | 描述 |
---|---|
Reflection | 为类的摘要信息提供静态函数export() |
ReflectionClass | 类信息和工具 |
ReflectionMethod | 类方法信息和工具 |
ReflectionParameter | 方法参数信息 |
ReflectionProperty | 类属性信息 |
ReflectionFunction | 函数信息和工具 |
ReflectionExtension | PHP扩展信息 |
ReflectionException | 错误类 |
开始行动
ReflectionClass提供给点信息的所有方法, 利用该对象,可以取得类的所有信息, 不管是PHP类置的还是用户自定义的。
class MyClass{
private $name;
public $address;
protected $telphone;
function __construct(){
}
function getFullMsg(){
echo $this->name ." " . $this->telphone . " " .$this->address;
}
}
//创建Myclass类的反射类对象, 通过该反射类对象, 可以获取MyClass的一切信息
$reflect = new ReflectionClass('MyClass');
//格式化输出类的信息
Reflection::export($reflect);
创建好ReflectionClass对象后, 就可以使用Reflection工具类输出MyClass类的相关信息。
其中export方法是Reflection类的静态方法,用于格式化和输出Reflection对象管理的数据。
以上代码调用export的输出为
Class [ class MyClass ] {
@@ E:\Apache\workplace\fs\index.php 3-19 - Constants [0] { }
- Static properties [0] { }
- Static methods [0] { }
- Properties [3] {
Property [ private $name ]
Property [ public $address ]
Property [ protected $telphone ] }
- Methods [2] {
Method [ public method __construct ] {
@@ E:\Apache\workplace\fs\index.php 11 - 13
}
Method [ public method getFullMsg ] {
@@ E:\Apache\workplace\fs\index.php 15 - 17
}
}
}
实例化$reflect = new ReflectionClass(‘MyClass’)后, 该对象常用的方法如下
//返回类的类名, 即MyClass
$reflect->getName();
//Boolean 是否是用户自定义的类, 是则返回true
$reflect->isUserDefined();
//Boolean 是否是php内置类, 是则返回true
$reflect->isInternal();
//Boolean 是否是接口, 是则返回true
$reflect->isInterface();
//Boolean 是否是抽象类, 是则返回true
$reflect->isAbstract();
//Boolean 是否是php内置类, 是则返回true
$reflect->isFinal();
//Boolean 该类是否final类型的类, 是则返回true
$reflect->isInternal();
利用ReflectionClass可以获取自定义类的源码, 实例如下:
class ReflectionClassUtil {
static function getClassSource (ReflectionClass $re) {
//获取类文件的绝对路径
$path = $re -> getFileName();
//打开该类所在的文件, 该处忽略错误信息
$lines = @file($path);
//获得类定义的起始行
$form = $re -> getStartLine();
//结束行
$to = $re -> getEndLine();
$len = $to - $form + 1;
//获取类定义代码
return implode(array_slice($lines, $form-1, $len));
}
}
接下来调用:
print ReflectionClassUtil::getClassSource(new ReflectionClass('MyClass'));
来获取该类定义的源码。
检查方法
像ReflectionClass可以检查检查类一样, ReflectionMethod对象可以检查类中的参数和方法。
获取ReflectionMethod有两种: ReflectionClass::getMethods()获得ReflectionMethod对象数组, 如果需要使用特定的方法, ReflectionClass::getMethod()可以接收一个方法名作为参数并返回相应的ReflectionMethod对象。
下表列举了ReflectionMethod对象的常用方法
方法名 | 描述 |
---|---|
$method->getName() | 获取方法名 |
$method->isUserDefined() | 是否是用户定义, 是则返回true |
$method->isInternal() | 是否是内置的, 是则返回true |
$method->isAbstract() | 是否是抽象, 是则返回true |
$method->isPublic() | 是否是public, 是则返回true |
$method->isProtected() | 是否是受保护的, 是则返回true |
$method->isPrivate() | 是否是私有的, 是则返回true |
$method->isConstract() | 是否是构造器, 是则返回true |
$method->returnReference() | 是否返回引用对象 |
检查方法中的参数
反射API提供了ReflectionParameter来帮助声明类方法是参数的限制, 要获取ReflectionParameter对象, 需要ReflectionMethod对象, ReflectionMethod::getParameters()方法返回参数数组。
该对象主要方法有(ReflectionParameter)
方法名 | 描述 |
---|---|
$parameter->getName() | 获取参数的变量名 |
$parameter->getClass() | 返回ReflectionClass对象 |
$parameter->getDeclaringClass() | 获得类的声明 |
$parameter->getPosition() | |
$parameter->isPassedByRefence() | 参数是否为引用 |
$parameter->isDefaultValueAvailable() |
PHP的反射在实际中用得不多, 笔者在这里只是简单的说明了下PHP反射api的使用教程, 具体使用场景和具体场景有关。比如可以利用PHP反射来自动加载第三方插件, 而不需要把第三方的代码硬编码到原有的系统中。