💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] # array_reduce **这个php的内置函数非常重要,laravel用这个函数完成,管道和中间件的执行** 在看array_reduce在laravel中的应用时,先来看看array_reduce官方文档是怎么说的。 array_reduce() 将回调函数 callback 迭代地作用到 array 数组中的每一个单元中,从而将数组简化为单一的值。 ~~~ mixed array_reduce ( array $array , callable $callback [, mixed $initial = NULL ] ) ~~~ 1. array > 输入的 array。 2. callback > mixed callback ( mixed $carry , mixed $item ) > $carry包括上次迭代的值,如果本次迭代是第一次,那么这个值是 initial,item 携带了本次迭代的值 3. initial > 如果指定了可选参数 initial,该参数将在处理开始前使用,或者当处理结束,数组为空时的最后一个结果。 从文档说明可以看出,array_reduce函数是把数组的每一项,都通过给定的callback函数,来简化的。 那我们就来看看是怎么简化的。 ~~~ $arr = ['AAAA', 'BBBB', 'CCCC']; $res = array_reduce($arr, function($carry, $item){ return $carry . $item; }); ~~~ 给定的数组长度为3,故总迭代三次。 1. 第一次迭代时 $carry = null $item = AAAA 返回AAAA 2. 第一次迭代时 $carry = AAAA $item = BBBB 返回AAAABBBB 3. 第一次迭代时 $carry = AAAABBBB $item = CCCC 返回AAAABBBBCCCC > 这种方式将数组简化为一串字符串AAAABBBBCCCC # 带初始值的情况 ~~~ $arr = ['AAAA', 'BBBB', 'CCCC']; $res = array_reduce($arr, function($carry, $item){ return $carry . $item; }, 'INITIAL-'); ~~~ 1. 第一次迭代时($carry = INITIAL-),($item = AAAA) 返回INITIAL-AAAA 2. 第一次迭代时($carry = INITIAL-AAAA),($item = BBBB), 返回INITIAL-AAAABBBB 3. 第一次迭代时($carry = INITIAL-AAAABBBB),($item = CCCC),返回INITIAL-AAAABBBBCCCC > 这种方式将数组简化为一串字符串INITIAL-AAAABBBBCCCC # 闭包 ~~~ $arr = ['AAAA', 'BBBB', 'CCCC']; //没带初始值 $res = array_reduce($arr, function($carry, $item){ return function() use ($item){//这里只use了item return strtolower($item) . '-'; }; }); ~~~ 1. 第一次迭代时,$carry:null,$item = AAAA,返回一个use了$item = AAAA的闭包 2. 第二次迭代时,$carry:use了$item = AAAA的闭包,$item = BBBB,返回一个use了$item = BBBB的闭包 3. 第一次迭代时,$carry:use了$item = BBBB的闭包,$item = CCCC,返回一个use了$item = CCCC的闭包 > 这种方式将数组简化为一个闭包,即最后返回的闭包,当我们执行这个闭包时$res()得到返回值CCCC- 上面这种方式只use ($item),每次迭代返回的闭包在下次迭代时,我们都没有用起来。只是又重新返回了一个use了当前item值的闭包。 # 闭包USE闭包 ~~~ $arr = ['AAAA']; $res = array_reduce($arr, function($carry, $item){ return function () use ($carry, $item) { if (is_null($carry)) { return 'Carry IS NULL' . $item; } }; }); ~~~ > 注意,此时的数组长度为1,并且没有指定初始值 由于数组长度为1,故只迭代一次,返回一个闭包 use($carry = null, $item = 'AAAA'),当我们执行($res())这个闭包时,得到的结果为Carry IS NULLAAAA。 接下来我们重新改造下, ~~~ $arr = ['AAAA', 'BBBB']; $res = array_reduce($arr, function($carry, $item){ return function () use ($carry, $item) { if (is_null($carry)) { return 'Carry IS NULL' . $item; } if ($carry instanceof \Closure) { return $carry() . $item; } }; }); ~~~ > 我们新增了一个条件判断,若当前迭代的值是一个闭包,返回该闭包的执行结果。 第一次迭代时,$carry的值为null,$item的值为AAAA,返回一个闭包, ~~~ //伪代码 function () use ($carry = null, $item = AAAA) { if (is_null($carry)) { return 'Carry IS NULL' . $item; } if ($carry instanceof \Closure) { return $carry() . $item; } } ~~~ 假设我们直接执行该闭包,将会返回Carry IS NULLAAAA的结果。 第二次迭代时,$carry的值为上述返回的闭包(伪代码),$item的值为BBBB,返回一个闭包, > 当我们执行这个闭包时,满足$carry instanceof \Closure,得到结果Carry IS NULLAAAABBBB。