对于一个Web应用来说,在一个请求真正处理前,我们可能会对请求做各种各样的判断,然后才允许后续处理。

我们通常的做法:

Script 01.php

Script 02.php

优点:直观,容易理解

缺点:

  1. 所有处理步骤放在一起,修改添加新步骤可能影响已有步骤;
  2. 单个处理步骤不具备可复用性。
  3. 同一个处理步骤的代码存在于多处,一个需求变更可能要修改多处代码。
  4. 整个处理流程不易扩展

Laravel 的请求处理管道:

Request,Middleware,Pipeline,Response

一个请求的处理,需要经过很多步骤(中间件),每个处理步骤(中间件)单独添加和修改,处理步骤(中间件)之间可以动态组合,从而使得每个处理步骤(中间件)可重用,也使得整个处理过程具备可扩展性。

Laravel 这种灵活的、可扩展的处理机制是如何实现的? ----- 管道模式(Pipeline

何为管道?

先来看一下自来处理流程:

原水,处理池,水管,饮用水

原水通过水管流经每个处理池,每个处理池中对水进行特定的处理,最后从水管中流出饮用水。

整个处理系统中,处理池可以随处理工艺的变更随时进行替换/新增/移除。

管道模式:

将整个处理流程划分成多个子任务,每个子任务对应一个任务模块,任务模块之间互相独立。当需要处理数据时,将本次所需任务模块按处理流程组装起来,前一个模块的输出作为后一个模块的输入,最后一个模块的输出即为最终处理结果。

输入数据,子处理模块,管道,输出数据
优点:
1. 各子模块相对独立
2. 每个子模块可复用
3. 处理流程可扩展(可以根据需求的不同,选择不同的子模块进行组合,满足要求)

用PHP实现管道模式:

 1 <?php
2
3 /**
4 * 管道 Demo
5 */
6
7 interface Middleware
8 {
9 public function handle();
10 }
11
12 class MyRequest implements Middleware
13 {
14 public function handle()
15 {
16 echo "【处理请求,返回响应】<br />";
17 }
18 }
19
20 abstract class MiddlewareAbstract implements Middleware
21 {
22 protected $next;
23
24 public function __construct(Middleware $middleware)
25 {
26 $this->next = $middleware;
27 }
28 }
29
30 class VerifyCsrfToken extends MiddlewareAbstract
31 {
32 public function handle()
33 {
34 echo "验证 CSRF Token<br />";
35 $this->next->handle();
36 echo "添加 CSRF Token<br />";
37 }
38 }
39
40 class StartSession extends MiddlewareAbstract
41 {
42 public function handle()
43 {
44 echo "开启 Session,获取会话数据<br />";
45 $this->next->handle();
46 echo "保存会话数据,关闭 Session<br />";
47 }
48 }
49
50 class EncryptCookies extends MiddlewareAbstract
51 {
52 public function handle()
53 {
54 echo "对输入 Cookie 进行解密<br />";
55 $this->next->handle();
56 echo "对输出 Cookie 进行加密";
57 }
58 }
59
60 class CheckMaintenanceMode extends MiddlewareAbstract
61 {
62 public function handle()
63 {
64 echo "检测系统是否处于维护状态<br />";
65 $this->next->handle();
66 }
67 }
68
69 class MyMiddleware extends MiddlewareAbstract
70 {
71 public function handle(){
72 echo "我新增的中间件<br />";
73 $this->next->handle();
74 }
75 }
76
77 $pipeline = new CheckMaintenanceMode(//检测系统是否处于维护状态
78 new EncryptCookies(//Cookie 加解密
79 new StartSession(//Session 相关处理
80 new MyMiddleware(
81 new VerifyCsrfToken(//Csrf Token 处理
82 new MyRequest() //处理请求,返回响应
83 )
84 )
85 )
86 )
87 );
88
89 $pipeline->handle();

Laravel 中管道的实现:

<?php
/**
* Laravel 管道
*/ interface Middleware
{
public function handle(Closure $next);
} class VerifyCsrfToken implements Middleware
{
public function handle(Closure $next)
{
echo "验证 CSRF Token<br />";
$next();
echo "添加 CSRF Token<br />";
}
} class StartSession implements Middleware
{
public function handle(Closure $next)
{
echo "开启 Session,获取会话数据<br />";
$next();
echo "保存会话数据,关闭 Session<br />";
}
} class EncryptCookies implements Middleware
{
public function handle(Closure $next)
{
echo "对输入 Cookie 进行解密<br />";
$next();
echo "对输出 Cookie 进行加密";
}
} class CheckMaintenanceMode implements Middleware
{
public function handle(Closure $next)
{
echo "检测系统是否处于维护状态<br />";
$next();
}
} /**
* 处理流程:
* 1. 检测系统是否处于维护状态
* 2. 对输入 Cookie 进行解密
* 3. 开启 Session,获取会话数据
* 4. 验证 CSRF Token
* 5. 处理请求,返回响应
* 6. 添加 CSRF Token
* 7. 保存会话数据,关闭 Session
* 8. 对输出 Cookie 进行加密
*/ function process()
{
$pipes = [
CheckMaintenanceMode::class,
EncryptCookies::class,
StartSession::class,
VerifyCsrfToken::class,
]; $firstSlice = function () {
echo "【处理请求,返回响应】<br />";
}; $pipes = array_reverse($pipes); $callStack = array_reduce($pipes, getSlice(), $firstSlice); $callStack();
} function getSlice()
{
return function ($stack, $pipe) {
return function () use ($stack, $pipe) {
return (new $pipe)->handle($stack);
};
};
} process();

Laravel 5.3 请求处理管道详解的更多相关文章

  1. ASP.NET Core真实管道详解[1]:中间件是个什么东西?

    ASP.NET Core管道虽然在结构组成上显得非常简单,但是在具体实现上却涉及到太多的对象,所以我们在 <ASP.NET Core管道深度剖析[共4篇]> 中围绕着一个经过极度简化的模拟 ...

  2. ASP.NET Core真实管道详解[1]

    ASP.NET Core管道虽然在结构组成上显得非常简单,但是在具体实现上却涉及到太多的对象,所以我们在 <ASP.NET Core管道深度剖析[共4篇]> 中围绕着一个经过极度简化的模拟 ...

  3. ASP.NET Core管道详解[2]: HttpContext本质论

    ASP.NET Core请求处理管道由一个服务器和一组有序排列的中间件构成,所有中间件针对请求的处理都在通过HttpContext对象表示的上下文中进行.由于应用程序总是利用服务器来完成对请求的接收和 ...

  4. ASP.NET Core管道详解[3]: Pipeline = IServer + IHttpApplication

    ASP.NET Core的请求处理管道由一个服务器和一组中间件构成,但对于面向传输层的服务器来说,它其实没有中间件的概念.当服务器接收到请求之后,会将该请求分发给一个处理器进行处理,对服务器而言,这个 ...

  5. ASP.NET Core管道详解[6]: ASP.NET Core应用是如何启动的?[下篇]

    要承载一个ASP.NET Core应用,只需要将GenericWebHostService服务注册到承载系统中即可.但GenericWebHostService服务具有针对其他一系列服务的依赖,所以在 ...

  6. ASP.NET Core真实管道详解[2]:Server是如何完成针对请求的监听、接收与响应的【上】

    Server是ASP .NET Core管道的第一个节点,负责完整请求的监听和接收,最终对请求的响应同样也由它完成.Server是我们对所有实现了IServer接口的所有类型以及对应对象的统称,如下面 ...

  7. Java Struts2 的请求处理流程详解

    一.Struts2的处理流程: 客户端产生一个HttpServletRequest的请求,该请求被提交到一系列的标准过滤器(Filter)组建链中(如ActionContextCleanUp:它主要是 ...

  8. Tomcat 请求处理流程详解

    Overview Connector 启动以后会启动一组线程用于不同阶段的请求处理过程. Acceptor 线程组.用于接受新连接,并将新连接封装一下,选择一个 Poller 将新连接添加到 Poll ...

  9. laravel 5.1 Model 属性详解

    <?php namespace Illuminate\Database\Eloquent; /** * 下面提到某些词的含义: * 1.覆盖: 在继承该类 \Illuminate\Databas ...

随机推荐

  1. Java IO 操作(一)

    (1)File 类的基础用法 // 1.创建 一个file 对象File file = new File("D:\\aaa");// 2.判断此 file 是否是一个文件夹file ...

  2. iOS 为键盘添加隐藏按钮

    // 为键盘添加隐藏按钮 UIToolbar * backView = [[UIToolbar alloc]initWithFrame:CGRectMake(, , , )]; [backView s ...

  3. BestCoder#51

    #include <cstdio> #include <iostream> #include <cmath> #include <cstring> us ...

  4. 【加精】手机话费充值API接口(PHP版)

    电商周年庆,公司搞了一个关注微信公众号送小额话费的活动,送1元.2元.5元.10元.20元.50元等不同面值的. 为了实现话费充值服务,找了多家开通了话费接口服务,接入后测试.先是做接口整合的平台,P ...

  5. __autoload()尝试加载未定义的类

    在PHP5之前,如果需要使用一个类,只需要直接使用include/require将其包含进来即可.PHP5 以后提供了这样一个方法可以自动完成加载所需的类文件. 参见官网的例子: ./myClass. ...

  6. C# asp.net 搭建微信公众平台(可实现关注消息与消息自动回复)的代码以及我所遇到的问题

    [引言] 利用asp.net搭建微信公众平台的案例并不多,微信官方给的案例是用PHP的,网上能找到的代码很多也是存在着这样那样的问题或者缺少部分方法,无法使用,下面是我依照官方文档写的基于.net 搭 ...

  7. 如何发布付费WP8应用

    如何发布付费应用,听起来蛮简单的,事实上也确实如此,但是发布付费WP8应用前的资料填写却让我郁闷不已. 我打开仪表板,点击进入账户--账户摘要,填写税务资料和付款账户,发现付款账户保存成功了,税务资料 ...

  8. js实现弹出的提示框只弹出一次

    <script type="text/javascript"> var ua = navigator.userAgent.toLowerCase(); if (/iph ...

  9. React-native之持久化保存----AsyncStorage

    AsyncStorage AsyncStorage是一个简单的,未加密的,异步的,持久化,关键值存储系统,是全局的. iOS中存储类似于NSUserDefault,存储问plist文件存放在设备中. ...

  10. 【JBOSS】数据库连接配置小结

    数据库驱动位置: %JBOSS_HOME%\server\default\lib目录下. 数据库配置文件位置:JBOSS_HOME\docs\examples\jca\XXXX-ds.xml < ...