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函數,這是語法不允許的,直接拋出如下錯誤:
Fatal error: Call-time pass-by-reference has been removed
- 新編Visual Basic程序設計上機實驗教程
- Oracle WebLogic Server 12c:First Look
- 云原生Spring實戰
- Mastering Swift 2
- MySQL數據庫管理與開發(慕課版)
- JavaScript 程序設計案例教程
- Python面向對象編程:構建游戲和GUI
- RabbitMQ Essentials
- App Inventor創意趣味編程進階
- Visual Studio 2015高級編程(第6版)
- 創意UI Photoshop玩轉移動UI設計
- 軟件工程與UML案例解析(第三版)
- Spring Boot學習指南:構建云原生Java和Kotlin應用程序
- JavaScript全棧開發
- 中小企業網站建設與管理(靜態篇)