作为程序员一定要保持良好的睡眠,才能好编程

ReflectionMethod获取反射方法并调用invoke执行注意事项

发布时间:2019-04-21


在在阅读框架源码的过程中,看到这样的一句话,不是太了解


fs1.jpg


随后进行了文档的查询:


ReflectionMethod::__construct


ReflectionMethod::__construct — ReflectionMethod 的构造函数


class Counter
{
    private static $c = 0;

    /**
     * Increment counter
     *
     * @final
     * @static
     * @access  public
     * @return  int
     */
    final public static function increment()
    {
        return ++self::$c;
    }
}

// Create an instance of the ReflectionMethod class
$method = new ReflectionMethod('Counter', 'increment');

// Print out basic information
printf(
    "===> The %s%s%s%s%s%s%s method '%s' (which is %s)\n" .
    "     declared in %s\n" .
    "     lines %d to %d\n" .
    "     having the modifiers %d[%s]\n",
        $method->isInternal() ? 'internal' : 'user-defined', 
        $method->isAbstract() ? ' abstract' : '', //是否抽象
        $method->isFinal() ? ' final' : '',
        $method->isPublic() ? ' public' : '',
        $method->isPrivate() ? ' private' : '',
        $method->isProtected() ? ' protected' : '',
        $method->isStatic() ? ' static' : '', //是否静态
        $method->getName(),
        $method->isConstructor() ? 'the constructor' : 'a regular method',
        $method->getFileName(),
        $method->getStartLine(),
        $method->getEndline(),
        $method->getModifiers(),
        implode(' ', Reflection::getModifierNames($method->getModifiers()))
);

// 打印注释文档
printf("---> Documentation:\n %s\n", var_export($method->getDocComment(), 1));

// 打印存在的静态变量
if ($statics= $method->getStaticVariables()) {
    printf("---> Static variables: %s\n", var_export($statics, 1));
}

// 执行方法
printf("---> Invocation results in: ");
var_dump($method->invoke(NULL));




invoke方法

参数 

object

如果执行的方法是静态类,那么这个参数传送 null


parameter

0,或者传送给方法的参数列表。可以通过这个参数,给方法传送大量的参数。


返回值 

返回方法的返回值


错误/异常 

如果 object 并没有包含一个可以使用的类实例,那么将产生 一个 ReflectionException。


如果方法调用失败,也会产生一个 ReflectionException。


去执行声明实例的这个方法。


代码如下:

class Stu{
    public function say($message){
        echo $message;
    }

    public static function dso($message){
        echo $message;
        return 'return'.$message;
    }
 }


//  $stu=new Stu();

// $stu->say('123');

//非静态方法,invoke第一个参数必须传递对象,否则报错
$ref=new ReflectionMethod(Stu::class,'say');
$result=$ref->invoke(new Stu,'message'.microtime(true));
echo "\n";

//这里调用的是静态方法,因此 invoke中的第一个参数可以传递 null
$ref=new ReflectionMethod(Stu::class,'dso');
$result=$ref->invoke(null,'message'.microtime(true));

var_dump($result);
echo "\n";


$result=call_user_func_array([Stu::class,'dso'], ['message'.microtime(true)]);


var_dump($result);
echo "\n";




invokeArgs方法

 class Stu{
    public function say($message){
        echo $message;
    }

    public static function dso($message,$who='jim'){
        //echo $message;
        return 'return:'.$who.','.$message;
    }
 }


$ref=new ReflectionMethod(Stu::class,'dso');

echo $ref->invokeArgs(null,['message'.time(),'james']);



第二个参数传递的是 数组,数组依次赋值给方法中的变量


进行一下验证:结果如下

$ref=new ReflectionMethod(Stu::class,'dso');

echo $ref->invokeArgs(null,['fff','message'.time(),'james']);
//return:message1555824750,fff