购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.7 回调函数

2.7.1 概 念

回调函数(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)

输出结果如下:

2.7.2 回调函数的使用

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个参数:

2.7.3 面试题:call_user_func()和call_user_func_array()的区别

题目描述: 请说明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函数,这是语法不允许的,直接抛出如下错误: gbQbodaL3tKGW5OheED7azZYKXPd2iovUTOaXAq8SfXYV4V3pz5cz8hDm5gfT0FF

     Fatal error: Call-time pass-by-reference has been removed
点击中间区域
呼出菜单
上一章
目录
下一章
×