回调函数(callbacks)类型可以将一个函数作为变量或参数传递给其他函数使用。在PHP中,诸如call_user_func、call_user_func_array、usort、uasort、uksort等函数,都可以接收一个函数作为参数。
为了演示回调函数的使用,我们举例如下,对以下数据按成绩高低进行排序。
使用到的函数usort(http://php.net/manual/zh/function.usort.php)定义如下:
bool usort ( array &$array , callable $value_compare_func )
参数array为参与排序的数组;value_compare_func是回调函数,用于比较两个数a和b的大小,大于时返回1,等于时返回0,小于时返回-1。
对表2-7中的数据按照成绩进行排序。
表2-7 成绩排序示例
程序代码如下:(源码文件:ch02/callback_usort.php)
输出结果如下:
PHP中的call_user_func()函数和call_user_func_array()函数都是回调函数,在写接口的时候经常会用到,但是它们有什么区别呢?
call_user_func()函数不支持引用参数,而call_user_func_array()支持引用参数,两者传入参数的方式不同。参见下述程序代码,观察两个回调函数的用法:
<?php function u_add($a1,$a2){ return $a1+$a2; } echo call_user_func('u_add',1,2); echo call_user_func_array('u_add',[1,2]);
这两个回调函数的第一个参数都是被调用的回调函数,call_user_func()还可以有多个参数,它们都是回调函数的参数,call_user_func_array()只有两个参数,第二个参数是要被传入回调函数的数组,这个数组得是索引数组。
如果传递一个数组给call_user_func_array(),数组的每个元素的值都会被当作一个参数传递给回调函数,数组的key回调掉。
如果传递一个数组给call_user_func(),整个数组会当作一个参数传递给回调函数,数组的key还会保留住。
比如有如下的回调函数:
我们分别使用call_user_func函数和call_user_func_array函数进行回调:
最后输出结果:
1个参数:
3个参数:
题目描述: 请说明call_user_func()和call_user_func_array()的区别有哪些?
解答: call_user_func()和call_user_func_array()都可以调用一个用户自定义的回调函数,它们的定义如下:
mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] ) mixed call_user_func_array ( callable $callback , array $param_arr )
可以看到,两个函数的第一个参数都是callback函数,不同之处有两个:
(1)参数数目不同。call_user_func可以接收多个参数,包括可变数量的参数;而call_user_func_array可接收一个数组作为参数。
(2)对引用传递参数的处理不同。call_user_func只能进行值传递,无法进行引用传递。而call_user_func_array支持引用传递。为加深大家的理解,我们看下面的代码示例。
(源码文件:ch02/callback_reference.php)
第2行定义了一个demo函数,其参数$a为引用传递参数。
第6行用call_user_func_array调用demo函数,并将$a=6以引用形式传递。
这时输出的$a=5,因为$a在demo函数里被重新赋值为5。
第8行用call_user_func调用demo函数,这是语法不允许的,直接抛出如下错误:
Fatal error: Call-time pass-by-reference has been removed