![PHP面试一战到底](https://wfqqreader-1252317822.image.myqcloud.com/cover/891/44509891/b_44509891.jpg)
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 成绩排序示例
![](https://epubservercos.yuewen.com/9146EB/23721566801954006/epubprivate/OEBPS/Images/Figure-T48_39605.jpg?sign=1739654173-ZEfEU0higpqkxJuOxcs3tGllJcNzkmUm-0-378b8dd27a9bf0c1b195032cd0f521f0)
程序代码如下:(源码文件:ch02/callback_usort.php)
![](https://epubservercos.yuewen.com/9146EB/23721566801954006/epubprivate/OEBPS/Images/Figure-P48_39603.jpg?sign=1739654173-Mgu7x4vS88b6WQ7cUzLOAcTrigAdit7e-0-c4daa4a4c7b9c1f9b7e6a85a629df015)
输出结果如下:
![](https://epubservercos.yuewen.com/9146EB/23721566801954006/epubprivate/OEBPS/Images/Figure-P48_39604.jpg?sign=1739654173-GRg0pphoev0C9iJYBIMbDDirFREYl31Z-0-ab9a83a46f0320e1bc5c7a4501c6f6ea)
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还会保留住。
比如有如下的回调函数:
![](https://epubservercos.yuewen.com/9146EB/23721566801954006/epubprivate/OEBPS/Images/Figure-P49_39607.jpg?sign=1739654173-zwra962J05PGlRvRq3cabOTmCetTfFHr-0-91e9c4557f1ae09e150fa8f90d9dfd58)
我们分别使用call_user_func函数和call_user_func_array函数进行回调:
![](https://epubservercos.yuewen.com/9146EB/23721566801954006/epubprivate/OEBPS/Images/Figure-P49_39608.jpg?sign=1739654173-Ypn97PZ6xtSXm7lkH5usos6lgCuJFBur-0-63b1f1f4ba594a7d63321783ca32b9d5)
最后输出结果:
1个参数:
![](https://epubservercos.yuewen.com/9146EB/23721566801954006/epubprivate/OEBPS/Images/Figure-P49_39610.jpg?sign=1739654173-L5APwme39SB49j7kLirBMjhrmSBlP4SB-0-d4ed130b494a40c4a465c93bc4adb17b)
3个参数:
![](https://epubservercos.yuewen.com/9146EB/23721566801954006/epubprivate/OEBPS/Images/Figure-P50_39612.jpg?sign=1739654173-fwXHfNpjRjW3bTJfiOx8BmwBTOp4H0DV-0-5d9d2f79ba6b4f19dd27ad5dbc3b5897)
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)
![](https://epubservercos.yuewen.com/9146EB/23721566801954006/epubprivate/OEBPS/Images/Figure-P50_39618.jpg?sign=1739654173-GgjTcBPdcGM4W9fl9RJFs8fgrbb6ksfE-0-479325942d2c54a4e989044ca9274a22)
第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