这样合理吗?不太好分辨,我们假设有一个记录请求和响应日志的中间件,这个时候,不论你把它放在什么位置,都不能完美的记录最初请求和最终日志。难道类似情况要写两个类,一个记录请求放在中间件数组第一个,一个处理响应,放在数组最后一位吗?不如在执行后面的foreach之前把middleware_arr数组给反转一下,这样就符合了要求:
@H_
$request = Illuminate\Http\Request::capture()
$request = A.before($request);
$request = B.before($request);
$response = $kernel->handle($request);
$response = B.after();
$response = A.after();
<?PHP
function rsum ( $v,$w )
{
$v += $w ;
return $v ;
}
function rmul ( $v,$w )
{
$v *= $w ;
return $v ;
}
$a = array( 1,2,3,4,5 );
$x = array();
$b = array_reduce ( $a,"rsum" );
$c = array_reduce ( $a,"rmul",10 );
?>
#输出:
这将使 $b 的值为 15, $c 的值为 1200(= 10*1*2*3*4*5)
#我们先假设只有一个middleware,叫log来简化情况,这里的类应该是一个类全路径,我这里就简单的写一下,要不然太长了。
$middleware_arr = ['log'];
#最终要执行的代码先封装成一个闭包,要不然没有办法传递到内层,如果用函数名传递函数的话,是没有办法传递参数的。
$default = function() use($request){
return $kernel->handle($request);
}
$callback = array_reduce($middleware_arr,function($stack,$pipe) {
return function() use($stack,$pipe){
return $pipe::handle($stack);
};
},$default);
# 这里 callback最终是 这样一个函数:
function() use($default,$log){
return $log::handle($default);
};
#所以每一个中间件都需要有一个方法handle方法,方法中要对传输的函数进行运行,类似如下,这里我类名就不大写了
class log implements Milldeware {
public static function handle(Closure $func)
{
$func();
}
}
#这里不难看出可以加入中间件自身逻辑如下:
class log implements Milldeware {
public static function handle(Closure $func)
{
#这里可以运行逻辑块before()
$func();
#这里可以运行逻辑块after()
}
}
$middleware_arr = ['csrf','log'];
#最终要执行的代码先封装成一个闭包,要不然没有办法传递到内层,$default);
# 这里 callback最终是 执行这样:
$log::handle(function() use($default,$csrf){
return $csrf::handle($default);
});