例
$func = 'callback';
$arg1 = 'Hello';
$arg2 = 'World';
$result = call_user_func($func, $arg1, $arg2);
echo $result;
function callback($arg1, $arg2){
return $arg1 . ' ' . $arg2;
}
テスト1
コード
require_once('Benchmark/Timer.php');
$func = 'concat';
$arg1 = 'Hello';
$arg2 = 'World';
$st = new str();
$b = new Benchmark_Timer();
$b->start();
for ($i = 0; $i < 100000; $i++){
concat($arg1, $arg2);
}
$b->setMarker('org');
for ($i = 0; $i < 100000; $i++){
call_user_func($func, $arg1, $arg2);
}
$b->setMarker('call_user_func');
for ($i = 0; $i < 100000; $i++){
$st->$func($arg1, $arg2);
}
$b->setMarker('string');
$b->display();
function concat($arg1, $arg2){
return $arg1 . ' ' . $arg2;
}
class str{
function concat($arg1, $arg2){
return $arg1 . ' ' . $arg2;
}
}
結果
-------------------------------------------------------------
marker time index ex time perct
-------------------------------------------------------------
Start 1213551357.49549100 - 0.00%
-------------------------------------------------------------
org 1213551358.56999200 1.074501 25.35%
-------------------------------------------------------------
call_user_func 1213551360.59016900 2.020177 47.66%
-------------------------------------------------------------
string 1213551361.73394500 1.143776 26.98%
-------------------------------------------------------------
Stop 1213551361.73417100 0.000226 0.01%
-------------------------------------------------------------
total - 4.238680 100.00%
-------------------------------------------------------------
テスト2:call_user_func
コード
require_once('Benchmark/Timer.php');
$func = 'concat';
$arg1 = 'Hello';
$arg2 = 'World';
$st = new str();
$b = new Benchmark_Timer();
$b->start();
for ($i = 0; $i < 100000; $i++){
call_user_func($func, $arg1, $arg2);
}
$b->setMarker('call_user_func');
for ($i = 0; $i < 100000; $i++){
call_user_func(array($st, 'concat'), $arg1, $arg2);
}
$b->setMarker('call_user_func(obj)');
for ($i = 0; $i < 100000; $i++){
call_user_func(array($st, 'concat'), $arg1, $arg2);
}
$b->setMarker('call_user_func_array(obj)');
for ($i = 0; $i < 100000; $i++){
call_user_func(array('str', 'concat'), $arg1, $arg2);
}
$b->setMarker('call_user_func(static)');
$b->display();
function concat($arg1, $arg2){
return $arg1 . ' ' . $arg2;
}
class str{
function concat($arg1, $arg2){
return $arg1 . ' ' . $arg2;
}
}
結果
------------------------------------------------------------------------
marker time index ex time perct
------------------------------------------------------------------------
Start 1213551872.93670100 - 0.00%
------------------------------------------------------------------------
call_user_func 1213551874.89791800 1.961217 21.03%
------------------------------------------------------------------------
call_user_func(obj) 1213551877.40661200 2.508694 26.90%
------------------------------------------------------------------------
call_user_func_array(obj) 1213551879.75447900 2.347867 25.17%
------------------------------------------------------------------------
call_user_func(static) 1213551882.26413500 2.509656 26.91%
------------------------------------------------------------------------
Stop 1213551882.26432900 0.000194 0.00%
------------------------------------------------------------------------
total - 9.327628 100.00%
------------------------------------------------------------------------
考察
・動的メソッド呼び出しは、call_user_funcを使うよりも$func()を使う方が速い。コードにそのままメソッド書くのと大して変わらない。
・クラスメソッドをstaticに呼び出す場合、staticキーワードをつけないと、1.5倍ぐらい遅くなる。
引数を可変にしたい場合はcall_user_func_arrayを使うしかないけど、そうでない場合は$func()を使う方がいい。call_user_funcと$func()の違いは、メソッドが存在しない場合、前者はWarningなのに対して、後者はFatalになる。