laravel很多地方写的很精湛, 用少量代码实现复杂功能, 可谓非常精巧。比如路中间件的实现。
/**
* Get a Closure that represents a slice of the application onion.
*
* @return \Closure
*/
protected function getSlice()
{
return function ($stack, $pipe) {
return function ($passable) use ($stack, $pipe) {
if ($pipe instanceof Closure) {
// If the pipe is an instance of a Closure, we will just call it directly but
// otherwise we'll resolve the pipes out of the container and call it with
// the appropriate method and arguments, returning the results back out.
return call_user_func($pipe, $passable, $stack);
} elseif (! is_object($pipe)) {
list($name, $parameters) = $this->parsePipeString($pipe);
// If the pipe is a string we will parse the string and resolve the class out
// of the dependency injection container. We can then build a callable and
// execute the pipe function giving in the parameters that are required.
$pipe = $this->container->make($name);
$parameters = array_merge([$passable, $stack], $parameters);
} else {
// If the pipe is already an object we'll just make a callable and pass it to
// the pipe as-is. There is no need to do any extra parsing and formatting
// since the object we're given was already a fully instantiated object.
$parameters = [$passable, $stack];
}
return call_user_func_array([$pipe, $this->method], $parameters);
};
};
}
调用路由的地方:
//这里的$pipes 是中间件名字, 或者 closure, 或者是个对象, $firstSlice是个路由调用(里面执行正确的 controller action)
return call_user_func(
array_reduce($pipes, $this->getSlice(), $firstSlice), $this->passable
);
这里的array_reduce, 实现了一个callback的堆栈, 将真正路由执行压在最下面。