原文地址:https://blog.csdn.net/qq_27682041/article/details/78909242
很多開(kāi)源的PHP框架和系統(tǒng),均有使用到call_user_func和call_user_func_array這兩個(gè)函數(shù),如CodeIgniter、ThinkPHP、Discuz等等。那么,這兩個(gè)函數(shù)有什么作用呢?又有什么區(qū)別呢?
兩個(gè)函數(shù)都是當(dāng)需要?jiǎng)討B(tài)調(diào)用函數(shù)時(shí)用到的,函數(shù)名不確定,參數(shù)不確定的情況下用到,至于區(qū)別下面會(huì)提到。
大部分PHP都知道,調(diào)用一個(gè)函數(shù),直接寫(xiě)函數(shù)名并和括號(hào)就可以了,如
調(diào)用沒(méi)有參數(shù)的函數(shù)
- 普通函數(shù)調(diào)用
<?php
function foo(){
return "bar";
}
echo foo();//調(diào)用foo()
輸出:bar
但是當(dāng)調(diào)用一個(gè)不存在的函數(shù)時(shí),就會(huì)報(bào)致命的錯(cuò)誤,如
<?php
$function = 'no_exist_func';
echo $function();
輸出:
Warning: call_user_func() expects parameter 1 to be a valid callback, function 'no_exist_func' not found or invalid function name而使用call_user_func_array調(diào)用時(shí),注意的是這個(gè)函數(shù)要求兩個(gè)參數(shù),需要傳2個(gè)參數(shù),如果沒(méi)函數(shù),傳個(gè)空數(shù)組,如:
<?php
echo call_user_func_array('no_exist_func',[]);
- 輸出:
Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'no_exist_func' not found or invalid function name
調(diào)用有參數(shù)的函數(shù)
- 普通函數(shù)調(diào)用
<?php
function foo($para1,$para2){
return $para1.'---'.$para2;
}
echo foo('bar1','bar2');
- 輸出:bar1---bar2
- call_user_func函數(shù)調(diào)用,參數(shù)傳入的是字符串形式,需要幾個(gè)參數(shù),就傳入幾個(gè)參數(shù),該函數(shù)可以傳n個(gè)參數(shù)
<?php
function foo($para1,$para2){
return $para1.'---'.$para2;
}
echo call_user_func('foo','bar1','bar2');
- 輸出:bar1---bar2
- call_user_func_array函數(shù)調(diào)用,參數(shù)傳入的是數(shù)組形式,該函數(shù)只有2個(gè)參數(shù)
<?php
function foo($para1,$para2){
return $para1.'---'.$para2;
}
echo call_user_func_array('foo',['bar1','bar2']);
- 輸出:bar1---bar2
面向?qū)ο髸r(shí)的調(diào)用
- 非靜態(tài)方法的調(diào)用
<code class="language-php"><?php
class Person {
public function getName($name,$age)
{
return "My name is ".$name.",I am ".$age." years old this year.";
}
}
echo call_user_func(array("Person", "getName"),"PHP","20");//嚴(yán)格模式下,雖然能輸出,但是會(huì)報(bào)錯(cuò),靜態(tài)方法才能這樣調(diào)用;Strict standards: call_user_func() expects parameter 1 to be a valid callback, non-static method Person::getName() should not be called statically
echo call_user_func(array(new Person(),"getName"),"GO","8");//輸出My name is GO,I am 8 years old this year. 無(wú)報(bào)錯(cuò)
echo call_user_func_array(array(new Person(),"getName"),array("GO","8"));//輸出My name is GO,I am 8 years old this year. 無(wú)報(bào)錯(cuò)</code>
- 輸出:
第一個(gè): Strict standards: call_user_func() expects parameter 1 to be a valid callback, non-static method Person::getName() should not be called statically
第二個(gè):My name is PHP,I am 20 years old this year.My name is GO,I am 8 years old this year.
第三個(gè):My name is GO,I am 8 years old this year.
- 靜態(tài)方法的調(diào)用
<?php
class Person {
public static function getName($name,$age)
{
return "My name is ".$name.",I am ".$age." years old this year.";
}
}
echo "use call_user_func:";
echo "<br>";
echo call_user_func(array("Person", "getName"),"PHP","20");
echo "<br>";
echo call_user_func("Person::getName","PHP","20");
echo "<br>";
echo call_user_func(['Person', 'getName'], "PHP","20");
echo "<br>";
echo call_user_func(array(new Person(),"getName"),"PHP","20");
echo "<br>";
echo "use call_user_func_array:";
echo "<br>";
echo call_user_func_array(array(new Person(),"getName"),array("GO","8"));
echo "<br>";
echo call_user_func_array(array("Person","getName"),array("GO","8"));
echo "<br>";
echo call_user_func_array(["Person","getName"],array("GO","8"));
echo "<br>";
- 輸出:
use call_user_func:
My name is PHP,I am 20 years old this year.
My name is PHP,I am 20 years old this year.
My name is PHP,I am 20 years old this year.
My name is PHP,I am 20 years old this year.
use call_user_func_array:
My name is GO,I am 8 years old this year.
My name is GO,I am 8 years old this year.
My name is GO,I am 8 years old this year.
引用傳遞
<?php
function reference(&$var)
{
$var++;
}
$a = 0;
call_user_func('reference', $a);//雖然輸出值0,但是報(bào)了警告 Warning: Parameter 1 to reference() expected to be a reference, value given
// call_user_func('reference', &$a);報(bào)致命錯(cuò)誤 //Fatal error: Call-time pass-by-reference has been removed
echo $a; // 0
call_user_func_array('reference', array(&$a));
echo $a; // 1
- 輸出:0 1
總結(jié):
1、call_user_func可以傳一個(gè)參數(shù),共有n個(gè)參數(shù),call_user_func_array只有2個(gè)參數(shù),必須傳2個(gè)參數(shù);
2、call_user_func傳的參數(shù)是字符串形式,call_user_func_array傳的參數(shù)是數(shù)組形式;
3、call_user_func不能引用傳遞傳參數(shù),call_user_func_array允許引用傳遞;
4、性能上call_user_func比call_user_func_array快。