Php 调用用户函数数组vs ReflectionMethod

Php 调用用户函数数组vs ReflectionMethod,php,Php,我想知道当使用上述函数调用类方法以使用数组动态填充方法调用时,最佳实践是什么 我有什么优点和缺点?我的意思是,在某些情况下,RefelectionMethod+invokeArgs选项似乎比call\u user\u函数快40%……但我是否遗漏了什么 谢谢 根据要求,我将为我的场景添加一个小基准,我需要通过引用。。。我知道这是一个非常具体的案例,这与上面的问题并不完全相关 class foo { public function bar(&$a, &$b, &$c) { /

我想知道当使用上述函数调用类方法以使用数组动态填充方法调用时,最佳实践是什么


我有什么优点和缺点?我的意思是,在某些情况下,RefelectionMethod+invokeArgs选项似乎比call\u user\u函数快40%……但我是否遗漏了什么

谢谢

根据要求,我将为我的场景添加一个小基准,我需要通过引用。。。我知道这是一个非常具体的案例,这与上面的问题并不完全相关

class foo { public function bar(&$a, &$b, &$c) { /* */ } }
$t1 = microtime(true);
$arr = array(1,2,3);
$foo = new foo;
$rfl = new ReflectionMethod('foo', 'bar');
for ($i=0; $i < 10000; ++$i)
{   
    $rfl->invokeArgs($foo, $arr);   
}

$t2 = microtime(true);
echo sprintf("\nElapsed reflectionmethod  : %f", $t2 - $t1);
$t1 = microtime(true);
$arr = array(1,2,3);
$foo = new foo;

for ($i=0; $i < 10000; ++$i)
{
    foreach( $arr as $k => $v ) $ref[$k] = &$arr[$k];       
    call_user_func_array( array($foo, 'bar'), $arr);
}

$t2 = microtime(true);
echo sprintf("\nElapsed calluserfuncarray : %f", $t2 - $t1);

我真的很想知道什么时候使用一个比另一个更好,以及为什么!但它与速度并没有严格的关系

不确定从哪里获得测试结果,但是
RefelectionMethod+invokeArgs选项比call\u user\u函数快40%
似乎很牵强,它只能通过单实例多调用实现

简单基准

set_time_limit(0);
echo "<pre>";
class Foo {

    public function bar($arg1, $arg2) {
    }
}

$globalRefection = new ReflectionMethod('Foo', 'bar');
$globalFoo = new Foo();

// Using call_user_func_array
function m1($args) {
    $foo = new Foo();
    call_user_func_array(array($foo,"bar"), $args);
}

// Using ReflectionMethod:invoke
function m2($args) {
    $foo = new ReflectionMethod('Foo', 'bar');
    $foo->invoke(new Foo(), $args[0], $args[1]);
}

// Using ReflectionMethod:invokeArgs
function m3($args) {
    $foo = new ReflectionMethod('Foo', 'bar');
    $foo->invokeArgs(new Foo(), $args);
}

// Using Global Reflection
function m4($args) {
    global $globalRefection;
    $globalRefection->invokeArgs(new Foo(), $args);
}

// Using Global Reflection + Glbal foo
function m5($args) {
    global $globalRefection, $globalFoo;
    $globalRefection->invokeArgs($globalFoo, $args);
}

$result = array('m1' => 0,'m2' => 0,'m3' => 0,'m4' => 0,'m5' => 0);
$args = array("arg1","arg2");

for($i = 0; $i < 10000; ++ $i) {
    foreach ( array_keys($result) as $key ) {
        $alpha = microtime(true);
        $key($args);
        $result[$key] += microtime(true) - $alpha;
    }
}

echo '<pre>';
echo "Single Run\n";
print_r($result);
echo '</pre>';
设置时间限制(0);
回声“;
福班{
公共功能栏($arg1,$arg2){
}
}
$globalRefection=新的ReflectionMethod('Foo','bar');
$globalFoo=新Foo();
//使用call\u user\u func\u数组
函数m1($args){
$foo=新foo();
调用用户函数数组(数组($foo,“bar”),$args);
}
//使用ReflectionMethod:invoke
函数m2($args){
$foo=新的ReflectionMethod('foo','bar');
$foo->invoke(新的foo(),$args[0],$args[1]);
}
//使用ReflectionMethod:invokeArgs
功能m3($args){
$foo=新的ReflectionMethod('foo','bar');
$foo->invokeArgs(新的foo(),$args);
}
//使用全局反射
函数m4($args){
全球$globalRefection;
$globalRefection->invokeArgs(新的Foo(),$args);
}
//使用全局反射+glbalfoo
函数m5($args){
全局$globalRefection,$globalFoo;
$globalRefection->invokeArgs($globalFoo,$args);
}
$result=数组('m1'=>0,'m2'=>0,'m3'=>0,'m4'=>0,'m5'=>0);
$args=数组(“arg1”、“arg2”);
对于($i=0;$i<10000;++$i){
foreach(数组_键($result)作为$key){
$alpha=微时间(真);
$key($args);
$result[$key]+=microtime(真)-$alpha;
}
}
回声';
回显“单次运行\n”;
打印(结果);
回声';
输出

单次运行
排列
(

[m1]=>0.018314599090845 0.024132013320923 0.021934270858765 0.012894868850708 0.01132345199585不确定从何处获得测试结果,但
RefelectionMethod+invokeArgs选项比call_user_函数快40%
似乎有些牵强,只有单实例多调用才能实现

简单基准

set_time_limit(0);
echo "<pre>";
class Foo {

    public function bar($arg1, $arg2) {
    }
}

$globalRefection = new ReflectionMethod('Foo', 'bar');
$globalFoo = new Foo();

// Using call_user_func_array
function m1($args) {
    $foo = new Foo();
    call_user_func_array(array($foo,"bar"), $args);
}

// Using ReflectionMethod:invoke
function m2($args) {
    $foo = new ReflectionMethod('Foo', 'bar');
    $foo->invoke(new Foo(), $args[0], $args[1]);
}

// Using ReflectionMethod:invokeArgs
function m3($args) {
    $foo = new ReflectionMethod('Foo', 'bar');
    $foo->invokeArgs(new Foo(), $args);
}

// Using Global Reflection
function m4($args) {
    global $globalRefection;
    $globalRefection->invokeArgs(new Foo(), $args);
}

// Using Global Reflection + Glbal foo
function m5($args) {
    global $globalRefection, $globalFoo;
    $globalRefection->invokeArgs($globalFoo, $args);
}

$result = array('m1' => 0,'m2' => 0,'m3' => 0,'m4' => 0,'m5' => 0);
$args = array("arg1","arg2");

for($i = 0; $i < 10000; ++ $i) {
    foreach ( array_keys($result) as $key ) {
        $alpha = microtime(true);
        $key($args);
        $result[$key] += microtime(true) - $alpha;
    }
}

echo '<pre>';
echo "Single Run\n";
print_r($result);
echo '</pre>';
设置时间限制(0);
回声“;
福班{
公共功能栏($arg1,$arg2){
}
}
$globalRefection=新的ReflectionMethod('Foo','bar');
$globalFoo=新Foo();
//使用call\u user\u func\u数组
函数m1($args){
$foo=新foo();
调用用户函数数组(数组($foo,“bar”),$args);
}
//使用ReflectionMethod:invoke
函数m2($args){
$foo=新的ReflectionMethod('foo','bar');
$foo->invoke(新的foo(),$args[0],$args[1]);
}
//使用ReflectionMethod:invokeArgs
功能m3($args){
$foo=新的ReflectionMethod('foo','bar');
$foo->invokeArgs(新的foo(),$args);
}
//使用全局反射
函数m4($args){
全球$globalRefection;
$globalRefection->invokeArgs(新的Foo(),$args);
}
//使用全局反射+glbalfoo
函数m5($args){
全局$globalRefection,$globalFoo;
$globalRefection->invokeArgs($globalFoo,$args);
}
$result=数组('m1'=>0,'m2'=>0,'m3'=>0,'m4'=>0,'m5'=>0);
$args=数组(“arg1”、“arg2”);
对于($i=0;$i<10000;++$i){
foreach(数组_键($result)作为$key){
$alpha=微时间(真);
$key($args);
$result[$key]+=microtime(真)-$alpha;
}
}
回声';
回显“单次运行\n”;
打印(结果);
回声';
输出

单次运行
排列
(

[m1]=>0.0183145990845 0.024132013320923 0.021934270858765 0.012894868850708 0.01132345199585“我的意思是,似乎RefelectionMethod+invokeArgs选项比call_user_函数快40%。”--你能为它添加一个测试用例吗?@zerkms我只做了一些具体的测试,但我最终会将它们添加到问题的末尾:)你知道,你可以在你的IDE中调整行距…@phant0m不是IDE,是我。我更喜欢它那样爆炸的时候!谢谢你修改了格式,顺便说一下,它节省了一些空间:)是的,但是有些IDE可以使行更高,这样你就可以得到多行的效果,而实际上没有任何物理上的限制(或者实际上,我应该说);“我的意思是,似乎RefelectionMethod+invokeArgs选项比call_user_函数快40%——你能为它添加一个测试用例吗?@zerkms我只做了一些具体的测试,但我最终会将它们添加到问题的末尾:)你知道,你可以调整IDE中的行距…@phantom不是IDE,是我。当它像那样爆炸时,我更喜欢它!谢谢你修改了格式,顺便说一句,它节省了一些空间:)是的,但是一些IDE可以使行更高,这样你就可以得到多行的效果,而实际上没有任何实际的行(或者我应该说是虚拟的)
Single Run
Array
(
    [m1] => 0.018314599990845   <----- call_user_func_array 
    [m2] => 0.024132013320923   <----- ReflectionMethod:invoke
    [m3] => 0.021934270858765   <----- ReflectionMethod:invokeArgs
    [m4] => 0.012894868850708   <----- Global Relection
    [m5] => 0.01132345199585    <----- Global Reflection + Global Foo
)