The following is Class Information.
TestClass is user defined.
TestClass can be instantiated.
The following is Class Source.
class TestClass {
    public $publicVariable;
 
    function __construct() {
 
    }
    private function privateMethod() {
 
    }
    function publicMethod() {
        print "This is publicMethod.\n";
    }
    function publicMethod2(string $arg1, int $arg2) {
 
    }
}
 
//这个函数中使用的ReflectionMethod中的方法都是非常简单直观的,就不再过多赘述了。
function methodInfo(ReflectionMethod $m) {
    $name = $m->getName();
    $details = "";
    if ($m->isUserDefined()) {
        $details .= "$name is user defined.\n";
    }
    if ($m->isInternal()) {
        $details .= "$name is built-in.\n";
    }
    if ($m->isAbstract()) {
        $details .= "$name is abstract.\n";
    }
    if ($m->isPublic()) {
        $details .= "$name is public.\n";
    }
    if ($m->isProtected()) {
        $details .= "$name is protected.\n";
    }
    if ($m->isPrivate()) {
        $details .= "$name is private.\n";
    }
    if ($m->isStatic()) {
        $details .= "$name is static.\n";
    }
    if ($m->isFinal()) {
        $details .= "$name is final.\n";
    }
    if ($m->isConstructor()) {
        $details .= "$name is constructor.\n";
    }
    if ($m->returnsReference()) {
        $details .= "$name returns a reference.\n";
    }
    return $details;
}
 
function methodSource(ReflectionMethod $m) {
    $path = $m->getFileName();
    $lines = @file($path);
    $from = $m->getStartLine();
    $to = $m->getEndLine();
    $len = $to - $from + 1;
    return implode(array_slice($lines, $from - 1, $len));
}
 
$rc = new ReflectionClass('TestClass');
$methods = $rc->getMethods();
print "The following is method information.\n";
foreach ($methods as $method) {
    print methodInfo($method);
    print "\n--------------------\n";
}
 
print "The following is Method[TestClass::publicMethod] source.\n";
print methodSource($rc->getMethod('publicMethod'));
复制代码
    运行结果如下:
 
复制代码
bogon:TestPhp$ php reflection_test.php 
The following is method information.
__construct is user defined.
__construct is public.
__construct is constructor.
 
--------------------
privateMethod is user defined.
privateMethod is private.
 
--------------------
publicMethod is user defined.
publicMethod is public.
 
--------------------
publicMethod2 is user defined.
publicMethod2 is public.
 
--------------------
The following is Method[TestClass::publicMethod] source.
    function publicMethod() {
        print "This is publicMethod.\n";
    }
复制代码
    让我们继续ReflectionParameter吧,他表示的是成员函数的参数信息。继续看代码吧。
 
复制代码
class ParamClass {
 
}
 
class TestClass {
    function publicMethod() {
        print "This is publicMethod.\n";
    }
    function publicMethod2(ParamClass $arg1, &$arg2, $arg3 = null) {
 
    }
}
 
function paramInfo(ReflectionParameter $p) {
    $details = "";
    //这里的$declaringClass将等于TestClass。
    $declaringClass = $p->getDeclaringClass();
    $name = $p->getName();
    $class = $p->getClass();
    $position = $p->getPosition();
    $details .= "\$$name has position $position.\n";
    if (!empty($class)) {
        $classname = $class->getName();
        $details .= "\$$name must be a $classname object\n";
    }
    if ($p->isPassedByReference()) {
        $details .= "\$$name is passed by reference.\n";
    }
    if ($p->isDefaultValueAvailable()) {
        $def = $p->getDefaultValue();
        $details .= "\$$name has default: $def\n";
    }
    return $details;
}
 
$rc = new ReflectionClass('TestClass');
$method = $rc->getMethod('publicMethod2');
$params = $method->getParameters();
 
foreach ($params as $p) {
    print paramInfo($p)."\n";
}
复制代码
    运行结果如下:
 
复制代码
bogon:TestPhp$ php reflection_test.php 
$arg1 has position 0.
$arg1 must be a ParamClass object
 
$arg2 has position 1.
$arg2 is passed by reference.
 
$arg3 has position 2.
$arg3 has default: 
复制代码
    上面介绍的都是通过PHP提供的Reflection API来遍历任意class的具体信息,事实上和Java等其他语言提供的反射功能一样,PHP也同样支持通过反射类调用实际对象的方法,这里将主要应用到两个方法,分别是ReflectionClass::newInstance()来创建对象实例,另一个是ReflectionMethod::invoke(),根据对象实例和方法名执行该方法。见如下代码:
 
复制代码
class TestClass {
    private $privateArg;
    function __construct($arg) {
        $this->privateArg = $arg;
    }
    function publicMethod() {
        print '$privateArg = '.$this->privateArg."\n";
    }
 
    function publicMethod2($arg1, $arg2) {
        print '$arg1 = '.$arg1.' $arg2 = '.$arg2."\n";
    }
}
 
$rc = new ReflectionClass('TestClass');
$testObj = $rc->newInstanceArgs(array('This is private argument.'));
$method = $rc->getMethod('publicMethod');
$method->invoke($testObj);
 
$method2 = $rc->getMethod('publicMethod2');
$method2->invoke($testObj,"hello","world");
复制代码
    运行结果如下:
 
bogon:TestPhp$ php reflection_test.php 
$privateArg = This is private argument.
$arg1 = hello $arg2 = world
    事实上ReflectionClass、ReflectionMethod和ReflectionParameter提供给我们的可用方法还有更多,这里只是给出几个最典型的方法,以便我们可以更为直观的学习和了解PHP Reflection API。相信再看完以后的代码示例之后,我们都会比较清楚,如果今后需要用到和class相关的功能,就从ReflectionClass中查找,而member function的信息则一定来自于ReflectionMethod,方法参数信息来自于ReflectionParameter。
 
注:该Blog中记录的知识点,是在我学习PHP的过程中,遇到的一些PHP和其他面向对象语言相比比较独特的地方,或者是对我本人而言确实需要簿记下来以备后查的知识点。虽然谈不上什么深度,但是还是希望能与大家分享。
						
http://www.bkjia.com/PHPjc/664271.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/664271.htmlTechArticle1. namespace: 和C++中的名字空间很像,作用也一样,都是为了避免在引用较多第三方库时而带来的名字冲突问题。通过名字空间,即便两个cl...