看 laravel 時遇到一個函數,琢磨了半天也沒有理解,最後還是查了下資料才完全理解。
這裏還是再做下筆記加深下印象。
php官方是這麼寫的:
array_reduce(array $array, callable $callback, [mixed $initial = null ])
什麼意思呢,先舉個簡單點兒的栗子:
<?php
function sum($carry, $item) {
var_dump($carry, $item);
$carry += $item;
echo '<br><hr>';
return $carry;
}
$a = array(1, 2, 3, 4, 5);
var_dump(array_reduce($a, 'sum', 10));
輸出結果爲:
int(10) int(1)
int(11) int(2)
int(13) int(3)
int(16) int(4)
int(20) int(5)
int(25)
可以看出 array_reduce
的第三個參數傳給 callable sum
並作爲第一個參數,然後 array $a
的第一個元素作爲第二個參數,即sum(10, 1)
,然後把計算結果返回給下一次迭代即 sum(11, 2),依次類推直至程序結束。
簡單的理解了,再來點複雜的,不過在開始之前,先來熟悉下匿名函數:
匿名函數:
$name = 'well';
$greet = function () use ($name){
echo 'hello ' ,$name;
};
$greet ();
# hello well
function closureFunc($name){
$func = function() use ($name){
echo "hello" ,$name;
};
$func();
}
closureFunc('well');
# hello well
接下來就是重點了,在 array_reduce
中使用匿名函數,舉個例子,西瓜姑娘接到閨蜜電話出去玩,肯定要先化妝打扮一下再出門:
class MakeUp {
public static function handle(Closure $next) {
echo '化妝打扮', '<br>';;
$next();
}
}
$firstSlice = function (){
echo '我要出去玩了~', '<br>';
};
$arr = [
'MakeUp'
];
function getSlice(){
return function ($stack, $pipe){
return function () use ($stack, $pipe){
return $pipe::handle($stack);
};
};
}
$go = array_reduce($arr, getSlice(), $firstSlice);
$go();
輸出結果爲:
化妝打扮
我要出去玩了~
這段程序執行時首先運行 getSlice($firstSlice, 'DressUp')
,然後拼裝執行 MakeUp::handle()
,MakeUp::handle()
中先去化妝打扮,然後再通過匿名Closure $next
執行 $firstSlice
出門去玩。
如果覺得僅僅是化妝還不夠,還要再穿條美美的裙子出門,那麼再對上邊的處理進行改造,添加穿裙子的過程:
class Skirt {
public static function handle(Closure $next) {
echo '穿上裙子', '<br>';
$next();
}
}
$arr = [
'MakeUp',
'Skirt'
];
那麼執行過程會變成什麼樣呢?爲了看清楚執行過程,先在 getSlice 中加上打印:
function getSlice(){
return function ($stack, $pipe){
echo '<pre>';
echo 'stack :';
var_dump($stack);
echo '<hr>';
echo 'pipe :';
var_dump($pipe);
echo '</pre>';
echo '<br><hr>';
return function () use ($stack, $pipe){
return $pipe::handle($stack);
};
};
}
可以看到第一次執行時,stack 是一個匿名函數 , 也對應了官網介紹的作爲第一次迭代時,$carry
是 initial
,也就是$firstSlice
。pipe
爲MakeUp
,但是它並沒有執行而是直接返回了,也就是直接返回
function ($stack, $pipe){
return function () use ($stack, $pipe){
return $pipe::handle($stack);
};
匿名函數 function ($stack, $pipe)
被返回後,也就相當於一個 array_reduce($arr, getSlice(), $firstSlice);
,不同的是匿名函數 function ($stack, $pipe)
代替了$firstSlice
被傳給下一次迭代。
第二次迭代時執行 Skire::handle
,先穿上了美美的裙子,然後$next
執行匿名函數 function ($stack, $pipe)
,也就是去MakeUp::handle
,化妝後繼續執行 $next
,也就是匿名函數 $firstSlice
。