php中call_user_func函数 和 call_user_func_array函数

PHP 中 call_user_func() 函数 和 call_user_func_array()函数都是回调函数

区别:

  • call_user_func()
    可以有多个参数,第一个参数为被调用的回调函数,除了第一个参数外,其他参数均为被调用函数的参数
  • call_user_func_array()
    只有两个参数,第一个参数为被调用的回调函数,第二个参数是要被传入回调函数的数组,这个数组必须是索引数组。

事例一:

  • call_user_func() 函数 和 call_user_func_array()区别
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php

function callBack() {

$args = func_get_args();
$num = func_num_args();

echo $num."个参数:";
echo "<pre>";
print_r($args);
echo "</pre>";
}

$arr = array(
'name' => 'liuli',
'sex' => 'boy'
);

------------------------------------------------------------------------------
call_user_func('callBack', $arr);

#输出结果
1个参数:
Array
(
[0] => Array
(
[name] => liuli
[sex] => boy
)

)
------------------------------------------------------------------------------
call_user_func_array('callBack', $arr);

#输出结果
2个参数:
Array
(
[0] => liuli
[1] => boy
)

事例二:

  • 匿名函数传参
1
2
3
4
5
6
7
8
9
<?php

call_user_func(function($args){

echo $args;

}, 1);
#输出结果
1

案例三:

  • 回调函数是匿名函数,并且匿名函数不设参数,通过其他方式获取参数的情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$arg1 = 'first';
$arg2 = 'two';
$return = call_user_func(function(){
$arg = func_get_arg(0); //func_get_arg函数作用:获取函数的第几个参数,必须要有参数,参数必须为函数参数的偏移量,0代表第一个参数
$args = func_get_args();//func_get_args的作用:获取函数所有的参数
if(func_num_args() == 1){//func_num_args函数的作用:获取函数参数的个数,注意,假如函数没有传参,该函数返回0
return $args[0];
}else{
//用|把函数的参数组织成字符串
return implode('|',$args);
}
},$arg1,$arg2);
var_dump($return);

#输出结果
string(9) "first|two"

事例四:

  • 调用没有命名空间类的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Func{
//静态方法
static public function _func(){
$str = 'THE CLASS NAME IS '.__CLASS__.' AND CLASS STATIC METHOD IS '.__METHOD__;
if(func_num_args()){
//获取函数参数,获取参数也可以通过给方法设置形参来获取,这里只是没给方法设置形参获取参数的情况
$arg = func_get_arg(0);
return $str.' and argument is '.$arg;
}else{
return $str;
}
}
//普通方法
public function __func($num){
return $num ? $num+1:$num;
}
}
//传递类的静态方法,有两种方式
//(1)种,传递····类名::方法名····
var_dump(call_user_func("Func::_func",'hell world'));//这里传递参数
//(2)种,传递类名和方法名的数组
var_dump(call_user_func(array('Func','_func')));//这里没有传参数
$num = 4;
$o = new Func;
//传递类普通方法必须用···数组···传递···该类的对象··和···方法名···
$return = call_user_func(array($o,'__func'),$num);
var_dump($return);
#输出结果
string(88) "THE CLASS NAME IS Func AND CLASS STATIC METHOD IS Func::_func and argument is hell world" string(61) "THE CLASS NAME IS Func AND CLASS STATIC METHOD IS Func::_func" int(5)

事例五:

  • 调用有命名空间的类方法的情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
//定义类的命名空间
namespace Home;
class Space{
//静态方法
static public function _call($num){
return $num +=10;
}
//普通方法
public function _func(){
return func_get_args();//返回函数的参数
}
}
//针对静态方法,有两种调用方式
//1.可以用array(__NAMESPACE__.'类名','方法名')传递类方法,也就是:array('命名空间类名','方法名')
$return = call_user_func(array(__NAMESPACE__.'Space','_call'),10);
//2.可以用···· __NAMESPACE__.'类名::方法名' ···传递类方法,也就是:'命名空间类名::方法名'
$return1 = call_user_func('HomeSpace::_call',100);
var_dump($return);
var_dump($return1);
//针对普通方法,不用传入命名空间即可调用,如下
$o = new Space;
$return = call_user_func(array($o,'_func'),1,2,3,4,5);
var_dump($return);

#输出结果
int(20) int(110) array(5) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) [4]=> int(5) }

事例六:

  • 调用php内置函数
1
2
3
4
5
6
<?php
$return = call_user_func('rtrim','sso;osoo;',';');
$return2 = call_user_func('explode',';','sso;osoo;');

#输出结果
string(8) "sso;osoo" array(3) { [0]=> string(3) "sso" [1]=> string(4) "osoo" [2]=> string(0) "" }

总结

  • call_user_func_array同理
  • 调用静态方法第一参数的两种方式:
    call_user_func("Func::_func", 'hello world')
    call_user_func(array('Func','_func'))
  • 调用普通方法的方式:
    call_user_func(array(new之后的对象, 方法名), 参数);
    例如:
1
2
3
$num = 4;
$o = new Func;
$return = call_user_func(array($o,'__func'),$num);