看 laravel 時(shí)遇到一個(gè)函數(shù),琢磨了半天也沒(méi)有理解,最后還是查了下資料才完全理解。
這里還是再做下筆記加深下印象宠页。
php官方是這么寫的:
array_reduce(array $array, callable $callback, [mixed $initial = null ])
什么意思呢礼饱,先舉個(gè)簡(jiǎn)單點(diǎn)兒的栗子:
<?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));
輸出結(jié)果為:
int(10) int(1)
int(11) int(2)
int(13) int(3)
int(16) int(4)
int(20) int(5)
int(25)
可以看出 array_reduce
的第三個(gè)參數(shù)傳給 callable sum
并作為第一個(gè)參數(shù)册倒,然后 array $a
的第一個(gè)元素作為第二個(gè)參數(shù)又官,即sum(10, 1)
延欠,然后把計(jì)算結(jié)果返回給下一次迭代即 sum(11, 2),依次類推直至程序結(jié)束税朴。
簡(jiǎn)單的理解了宰啦,再來(lái)點(diǎn)復(fù)雜的肴颊,不過(guò)在開始之前服猪,先來(lái)熟悉下匿名函數(shù):
匿名函數(shù):
$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
接下來(lái)就是重點(diǎn)了供填,在 array_reduce
中使用匿名函數(shù),舉個(gè)例子罢猪,西瓜姑娘接到閨蜜電話出去玩近她,肯定要先化妝打扮一下再出門:
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();
輸出結(jié)果為:
化妝打扮
我要出去玩了~
這段程序執(zhí)行時(shí)首先運(yùn)行 getSlice($firstSlice, 'DressUp')
,然后拼裝執(zhí)行 MakeUp::handle()
膳帕,
MakeUp::handle()
中先去化妝打扮粘捎,然后再通過(guò)匿名Closure $next
執(zhí)行 $firstSlice
出門去玩。
如果覺得僅僅是化妝還不夠,還要再穿條美美的裙子出門攒磨,那么再對(duì)上邊的處理進(jìn)行改造泳桦,添加穿裙子的過(guò)程:
class Skirt {
public static function handle(Closure $next) {
echo '穿上裙子', '<br>';
$next();
}
}
$arr = [
'MakeUp',
'Skirt'
];
那么執(zhí)行過(guò)程會(huì)變成什么樣呢?為了看清楚執(zhí)行過(guò)程娩缰,先在 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);
};
};
}
可以看到第一次執(zhí)行時(shí),stack 是一個(gè)匿名函數(shù) , 也對(duì)應(yīng)了官網(wǎng)介紹的作為第一次迭代時(shí)漆羔,$carry
是 initial
,也就是$firstSlice
狱掂。pipe
為MakeUp
,但是它并沒(méi)有執(zhí)行而是直接返回了演痒,也就是直接返回
function ($stack, $pipe){
return function () use ($stack, $pipe){
return $pipe::handle($stack);
};
匿名函數(shù) function ($stack, $pipe)
被返回后,也就相當(dāng)于一個(gè) array_reduce($arr, getSlice(), $firstSlice);
趋惨,不同的是匿名函數(shù) function ($stack, $pipe)
代替了$firstSlice
被傳給下一次迭代鸟顺。
第二次迭代時(shí)執(zhí)行 Skire::handle
,先穿上了美美的裙子器虾,然后$next
執(zhí)行匿名函數(shù) function ($stack, $pipe)
讯嫂,也就是去MakeUp::handle
,化妝后繼續(xù)執(zhí)行 $next
兆沙,也就是匿名函數(shù) $firstSlice
欧芽。
emmm,你大神就是你大神葛圃,不能不服氣千扔。