1. 程式人生 > >回調、匿名函數和閉包

回調、匿名函數和閉包

pub 第一個 ble else message run tin 函數應用 cnblogs

(1) is_callable用來檢測傳進來的值能被call_user_func或者array_walk等函數使用,它非常智能,能夠測試數組,數組形式的有效回調應該是以對象作為第一個元素,以方法名作為第二個元素,類似 array(‘new SomeClass()‘, ‘someFunc‘)。

下面用例子來說明:

 1 function a(){
 2 
 3 }
 4 
 5 $a = ‘a‘;
 6 
 7 if(is_callable($a)){
 8 
 9     echo ‘a is callable <br>‘;
10 
11 } else {
12 13 echo ‘a is not callable <br>‘; 14 15 }

輸出:

1 a is callable 
 1 class B{
 2 
 3     public function add($arg = []){
 4 
 5         echo ‘sum: ‘ . ($arg[0] + $arg[1]) . ‘<br>‘;
 6 
 7     }
 8 
 9 }
10 
11 $c = [new B(), ‘add‘];
12 
13 if(is_callable($c)){
14 15 call_user_func($c, [1, 2]); 16 17 }

輸出:

1 sum: 3

(2) array_walk 將用戶自定義函數應用到數組中的每一個元素。

例子:

 1 $array = [1, 2, 3];
 2 
 3 function show($v, $k, $u){
 4 
 5     $v += 1;
 6 
 7     echo "u: {$u}, k: {$k}, v: {$v}<br>";
 8 
 9 }
10 
11 array_walk($array, ‘show‘, ‘Jerry‘);
12 13 echo ‘<pre>‘; 14 15 print_r($array);

在這個例子中,需要註意,array_walk函數第一個參數為數組名,第二個參數為回調函數名,第三個為用戶自定義參數,在本例中,show函數的第一個參數為數組$array的值,第二個參數為數組$array的鍵值或者索引,第三個參數為用戶自定義參數,對應著array_walk的第三個參數,本例輸出如下:

 1 u: Jerry, k: 0, v: 2
 2 u: Jerry, k: 1, v: 3
 3 u: Jerry, k: 2, v: 4
 4 
 5 Array
 6 
 7 (
 8 
 9     [0] => 1
10 
11     [1] => 2
12 
13     [2] => 3
14 
15 )

如果想在show函數處理完之後同時改變原數組$array的值,可以在show函數的第一個參數前使用&引用地址符,示例如下:

 1 $array = [1, 2, 3];
 2 
 3 function show(&$v, $k, $u){
 4 
 5     $v += 1;
 6 
 7     echo "u: {$u}, k: {$k}, v: {$v}<br>";
 8 
 9 }
10 
11 array_walk($array, ‘show‘, ‘Jerry‘);
12 
13 echo ‘<pre>‘;
14 
15 print_r($array);

通過改變$v的值,同時改變數組$array的值,輸出:

 1 u: Jerry, k: 0, v: 2
 2 u: Jerry, k: 1, v: 3
 3 u: Jerry, k: 2, v: 4
 4 
 5 Array
 6 
 7 (
 8 
 9     [0] => 2
10 
11     [1] => 3
12 
13     [2] => 4
14 
15 )

(3) call_user_func將其第一個參數作為回調函數使用,其余參數當做該回調函數的參數。

 1 function d($a, $b, $c){
 2 
 3     echo "a: {$a}, b: {$b}, c: {$c}<br>";
 4 
 5 }
 6 
 7 $f = ‘d‘;
 8 
 9 if(is_callable($f) && function_exists($f)){
10 
11     call_user_func($f, ‘Kue‘, ‘Sub‘, ‘Dod‘);
12 
13 }

輸出:

1 a: Kue, b: Sub, c: Dod

(4) create_function創建匿名函數,第一個參數為該匿名函數的參數,第二個參數為匿名函數的函數體。

1 $n = create_function(‘$a, $b‘, ‘return $a + $b;‘);
2 
3 echo $n(1,2).‘<br>‘;

輸出:3

其中,這個例子需要註意的地方是,第二個參數語句完成之後不要忘記加分號,如果不加會報錯,錯誤信息如下:

1 Parse error:  syntax error, unexpected ‘}‘, expecting ‘;‘ in : runtime-created function on line 1

(5) 在PHP5.3以後,有更好的方式來實現create_function的功能,這就是內聯函數的使用。

1 $e = function($arg){
2 
3     echo "arg: {$arg}<br>";
4 
5 };
6 
7 $e(‘Hello world!‘);

這是內聯函數的基本用法,其中函數體結束需要以分號結束,本例會輸出:

1 arg: Hello world!

(6) 閉包 use

 1 function message($m){
 2 
 3     $close = ‘door‘;
 4 
 5     $h = function($m) use(&$close, $m){
 6 
 7         echo "{$m} close the {$close} please!<br>";
 8 
 9         $close = ‘nali‘;
10 
11     };
12 
13     $h(‘Lily‘);
14 
15     echo $close.‘<br>‘;
16 
17 }
18 
19 echo call_user_func(‘message‘, ‘Jim‘);

輸出:

1 Jim close the door please!
2 
3 nali
本例中 use 關鍵字將變量$close與內聯函數$h連接在一起,如果$close前面不加&地址符,則$close的值不會改變,加上&之後,$close的值會隨之改變。

回調、匿名函數和閉包