700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > laravel框架的中间件middleware的详解

laravel框架的中间件middleware的详解

时间:2024-01-08 16:02:59

相关推荐

laravel框架的中间件middleware的详解

php框架|Laravel

php,laravel

php框架-Laravel

本篇文章给大家带来的内容是关于laravel框架的中间件middleware的详解,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

房地产公司网站源码,vuejs使用vscode,ubuntu安装怎么带密码,tomcat标准写法,sqlite日期加几天,table固定列 插件,php简单前端框架slim,成都爬虫式胃镜,php 数组 最后,无锡seo关键词优化,asp工资查询网站源码,手机网页左右翻页,一些公司网站的模板,flash超炫欢迎页面,sql汽车美容管理系统,人人商城小程序设置强制登陆lzw

laravel中间件是个非常方便的东西,能将一些逻辑实现解耦,并且在laravel中,

中间件的编写也是非常的方便。谁用谁知道。

刷单管理网站源码,ubuntu界面怎么变大,tomcat6 启动闪退,图片爬虫工具推荐,php实现验证码判断 源码,谷歌seo 兼职lzw

1.装饰器模式

unity3d 5.x 源码,ubuntu 安装网络驱动,vue能发布到tomcat,爬虫怎么突破,php课程用英文表示,小店seolzw

laravel中的中间件使用的就是装饰器模式,什么是[装饰器模式][1],先去了解一下吧,这里大概说一下,就是这个模式主要的就是用于解决 当一个类需要动态扩展功能的时候,使用继承的方式会让子类膨胀,并且这个扩展的功能是个公用功能的情况下,不利于功能的复用以及代码的解耦。

在laravel,使用对于使用这种模式的功能,称为请求处理管道,也就是pipeline

//公共接口interface middleware { public static function handle(Closure $next); }//装饰器1class MiddleStepOne implements middleware{ public static function handle(Closure $next) { echo "前期处理的第一步"."

"; $next(); echo "后期处理的第一步"."

"; } }//装饰器2class MiddleStepTwo implements middleware{ public static function handle(Closure $next) { echo "前期处理的第二步"."

"; $next(); echo "后期处理的第二步"."

"; }}function goFunc() { return function ($step,$className) {return function () use ($step,$className) {return $className::handle($step);}; };}$pip = array( MiddleStepOne::class, MiddleStepTwo::class,);$pip = array_reverse($pip); //反转数组,以求达到要求的顺序运行$first = function (){ echo "前期处理完毕"."

";}; //实际要处理的函数$a = array_reduce($pip,goFunc(),$first); //遍历pip数组,并将first作为第一个参数传递进去$a(); //执行

输出:

这个就是一个简单的基于装饰器模式的管道。他的本质其实就是基于闭包和递归。

通过分析这个程序,对于最终生成的$a变量,它的值大概是这样的 MiddleStepOne.handle(MiddleStepTwo.handle(first)),当执行的时候因为在handle中有个next()函数的存在,所以这是一个递归的调用。对于laravel的中间件,他的实现原理也是和这个一样的。

2.laravel中的中间件和请求处理管道

在laravel中,我们我们可以通过设置中间件来在请求执行之前做一些预先的处理。

从请求入口 public/index.php开始

重要的是这段代码:即 处理请求,返回请求的响应

$response = $kernel->handle($request = Illuminate\Http\Request::capture() //创建一个请求实例);

接着我们进入kernel中看他的具体实现 IlluminateFoundationHttpKernel.php中

关于dispatchToRouter()函数请大家自己去看,这里就不多说了。

接下来就是激动人心的PipeLine类了,

container = $container; } /*** Set the object being sent through the pipeline.** @param mixed $passable* @return $this*/ public function send($passable) { $this->passable = $passable; return $this; } /*** Set the array of pipes.** @param array|mixed $pipes* @return $this*/ public function through($pipes) { $this->pipes = is_array($pipes) ? $pipes : func_get_args(); return $this; } /*** Set the method to call on the pipes.** @param string $method* @return $this*/ public function via($method) { $this->method = $method; return $this; } /*** Run the pipeline with a final destination callback.** @param \Closure $destination* @return mixed*/ public function then(Closure $destination) { $pipeline = array_reduce( array_reverse($this->pipes), $this->carry(), $this->prepareDestination($destination) ); return $pipeline($this->passable); } /*** Get the final piece of the Closure onion.** @param \Closure $destination* @return \Closure*/ protected function prepareDestination(Closure $destination) { return function ($passable) use ($destination) { return $destination($passable); }; } /*** Get a Closure that represents a slice of the application onion.** @return \Closure*/ protected function carry() { return function ($stack, $pipe) { return function ($passable) use ($stack, $pipe) {if (is_callable($pipe)) { // If the pipe is an instance of a Closure, we will just call it directly but // otherwise well resolve the pipes out of the container and call it with // the appropriate method and arguments, returning the results back out. //如果pip也就中间件函数是一个闭包可调用函数,就直接返回这个闭包函数就行了 //这里我还没有找到对应的使用场景,后续补充 return $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->getContainer()->make($name); $parameters = array_merge([$passable, $stack], $parameters);} else { // If the pipe is already an object well 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 e given was already a fully instantiated object. $parameters = [$passable, $stack];}return method_exists($pipe, $this->method)? $pipe->{$this->method}(...$parameters): $pipe(...$parameters); }; }; } /*** Parse full pipe string to get name and parameters.** @param string $pipe* @return array*/ protected function parsePipeString($pipe) { list($name, $parameters) = array_pad(explode(:, $pipe, 2), 2, []); if (is_string($parameters)) { $parameters = explode(,, $parameters); } return [$name, $parameters]; } /*** Get the container instance.** @return \Illuminate\Contracts\Container\Container* @throws \RuntimeException*/ protected function getContainer() { if (! $this->container) { throw new RuntimeException(A container instance has not been passed to the Pipeline.); } return $this->container; }}

总的来说pipeLine类的实现和我之前写的修饰器是差不多,这里主要麻烦的地方就在于就在于

protected function carry()函数内部,对于当pip是闭包,字符串,还有对象的处理。

之前觉得laravel的中间件是个很神秘的东西,但是看了之后才觉得也就那样,很精巧,在实际开发中这种模式也是很有帮助的,例如我们目前用的一个gateway项目,因为没有使用任何框架,所以将判断条件剥离,写入到中间件中, 这样实现了一定程度上的模块化编程。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。