![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=1739224947-yAcMV6HgGV5mcoQAbWFTZ6iHl6DUk9bD-0-f3bcbbcb490ff1e6727a0b33850ea4c5)
程序代码如下:(源码文件:ch02/callback_usort.php)
![](https://epubservercos.yuewen.com/9146EB/23721566801954006/epubprivate/OEBPS/Images/Figure-P48_39603.jpg?sign=1739224947-wxYOawZ3rXWez1GJZIWxCI0pqYlBmmRQ-0-16012ba50185c279a1f57a6ea388486b)
输出结果如下:
![](https://epubservercos.yuewen.com/9146EB/23721566801954006/epubprivate/OEBPS/Images/Figure-P48_39604.jpg?sign=1739224947-5C9ojgtigHvy01crx45113afsgANRXK3-0-94f81458ac57bcaaab71ecf278b8f8ff)
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=1739224947-gYopeSGikCvaUr4nOXHkysKX9Gc1uC7K-0-ce8cb0733beedac0637c7203bbf8aba9)
我们分别使用call_user_func函数和call_user_func_array函数进行回调:
![](https://epubservercos.yuewen.com/9146EB/23721566801954006/epubprivate/OEBPS/Images/Figure-P49_39608.jpg?sign=1739224947-8Kk3y4ujiOCslYiV5lI6FP2b6GURqFin-0-82a12bedc480dfeb15912d46e0acfbbb)
最后输出结果:
1个参数:
![](https://epubservercos.yuewen.com/9146EB/23721566801954006/epubprivate/OEBPS/Images/Figure-P49_39610.jpg?sign=1739224947-DYXRbIA1wsx5WSDDJGexWoAm4Wa9EedP-0-5fcd294e501dbf8e8d0853042b226f03)
3个参数:
![](https://epubservercos.yuewen.com/9146EB/23721566801954006/epubprivate/OEBPS/Images/Figure-P50_39612.jpg?sign=1739224947-vSvQdOvKQSdXKvHm7L3W7RfnFbPTxXHX-0-a17660c0835780a3e79c6484f32b30b1)
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=1739224947-NXIeyw8v39XVkTpKBvEYYl1ZRtAmcafW-0-953c87d93d2c71b21ec37c74a3315044)
第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