多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
<article><h1>Laravel 的路由中间件</h1><ul><li><a href="#introduction">简介</a></li><li><a href="#defining-middleware">创建中间件</a></li><li><a href="#registering-middleware">注册中间件</a><ul><li><a href="#global-middleware">全局中间件</a></li><li><a href="#assigning-middleware-to-routes">为路由指定中间件</a></li><li><a href="#middleware-groups">中间件组</a></li></ul></li><li><a href="#middleware-parameters">中间件参数</a></li><li><a href="#terminable-middleware">Terminable 中间件</a></li></ul><p><a name="introduction"></a></p><h2><a href="#introduction">简介</a></h2><p>Laravel 中间件提供了一种方便的机制来过滤进入应用的 HTTP 请求,例如,Laravel 包含验证用户身份权限的中间件。如果用户没有通过身份验证,中间件会重定向到登录页,引导用户登录。反之,中间件将允许该请求继续传递到应用程序。</p><p>当然,除了身份验证以外,中间件还可以被用来执行各式各样的任务,如:CORS 中间件负责为所有即将离开应用的响应添加适当的头信息;日志中间件可以记录所有传入应用的请求。</p><p>Laravel 已经内置了一些中间件,包括身份验证、CSRF 保护等。所有的中间件都放在 <code class=" language-php">app<span class="token operator">/</span>Http<span class="token operator">/</span>Middleware</code> 目录内。</p><p><a name="defining-middleware"></a></p><h2><a href="#defining-middleware">创建中间件</a></h2><p>使用 <code class=" language-php">make<span class="token punctuation">:</span>middleware</code> 这个 Artisan 命令创建新的中间件:</p><pre class=" language-php"><code class=" language-php">php artisan make<span class="token punctuation">:</span>middleware CheckAge</code></pre><p>该命令将会在 <code class=" language-php">app<span class="token operator">/</span>Http<span class="token operator">/</span>Middleware</code> 目录内新建一个 <code class=" language-php">CheckAge</code> 类。在这个中间件内,我们仅允许请求的 <code class=" language-php">age</code> 参数大于 200 时访问该路由,否则,会将用户请求重定向到 <code class=" language-php">home</code> URI 。</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter">&lt;?php</span> <span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Middleware</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Closure</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">CheckAge</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">/** * 处理传入的请求 * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">handle<span class="token punctuation">(</span></span><span class="token variable">$request</span><span class="token punctuation">,</span> Closure <span class="token variable">$next</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token property">age</span> <span class="token operator">&lt;=</span> <span class="token number">200</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">redirect<span class="token punctuation">(</span></span><span class="token string">'home'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token variable">$next</span><span class="token punctuation">(</span><span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre><p>如你所见,若请求参数 <code class=" language-php">age</code> 小于等于 <code class=" language-php"><span class="token number">200</span></code>,中间件将返回给客户端 HTTP 重定向,反之应用程序才会继续处理该请求。若将请求继续传递到应用程序(即允许通过中间件验证),只需将 <code class=" language-php"><span class="token variable">$request</span></code> 作为参数调用 <code class=" language-php"><span class="token variable">$next</span></code> 回调函数。</p><p>最好将中间件想象为一系列的「层」,HTTP 请求必须经过它们才会触发您的应用程序。每一层都可以检测接收的请求,甚至可以完全拒绝请求访问您的应用。</p><h3>前置中间件 / 后置中间件</h3><p>中间件运行在请求之前或之后取决于中间件本身。例如,以下中间件会在请求被应用处理 <strong>之前</strong> 执行一些任务</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter">&lt;?php</span> <span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Middleware</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Closure</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">BeforeMiddleware</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">handle<span class="token punctuation">(</span></span><span class="token variable">$request</span><span class="token punctuation">,</span> Closure <span class="token variable">$next</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true"> // 执行动作 </span> <span class="token keyword">return</span> <span class="token variable">$next</span><span class="token punctuation">(</span><span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre><p>然而,这个中间件会在请求被应用处理 <strong>之后</strong> 执行它的任务:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter">&lt;?php</span> <span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Middleware</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Closure</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">AfterMiddleware</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">handle<span class="token punctuation">(</span></span><span class="token variable">$request</span><span class="token punctuation">,</span> Closure <span class="token variable">$next</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$response</span> <span class="token operator">=</span> <span class="token variable">$next</span><span class="token punctuation">(</span><span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true"> // 执行动作 </span> <span class="token keyword">return</span> <span class="token variable">$response</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre><p><a name="registering-middleware"></a></p><h2><a href="#registering-middleware">注册中间件</a></h2><p><a name="global-middleware"></a></p><h3>全局中间件</h3><p>如果你希望访问你应用的每个 HTTP 请求都经过某个中间件,只需将该中间件类列入 <code class=" language-php">app<span class="token operator">/</span>Http<span class="token operator">/</span>Kernel<span class="token punctuation">.</span>php</code> 类里的 <code class=" language-php"><span class="token variable">$middleware</span></code> 属性。</p><p><a name="assigning-middleware-to-routes"></a></p><h3>为路由指定中间件</h3><p>如果你想为特殊的路由指定中间件,首先应该在 <code class=" language-php">app<span class="token operator">/</span>Http<span class="token operator">/</span>Kernel<span class="token punctuation">.</span>php</code> 文件内为该中间件指定一个 <code class=" language-php">键值</code>。默认情况下 <code class=" language-php">Kernel</code> 类的 <code class=" language-php"><span class="token variable">$routeMiddleware</span></code> 属性已经包含了 Laravel 内置的中间件条目。加入自定义的中间件,只需把它附加到此列表并指定你定义的<code class=" language-php">键值</code>即可。例如:</p><pre class=" language-php"><code class=" language-php"><span class="token comment" spellcheck="true">// App\Http\Kernel 类内 </span> <span class="token keyword">protected</span> <span class="token variable">$routeMiddleware</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string">'auth'</span> <span class="token operator">=</span><span class="token operator">&gt;</span> \<span class="token scope">Illuminate<span class="token punctuation">\</span>Auth<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>Authenticate<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token string">'auth.basic'</span> <span class="token operator">=</span><span class="token operator">&gt;</span> \<span class="token scope">Illuminate<span class="token punctuation">\</span>Auth<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>AuthenticateWithBasicAuth<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token string">'bindings'</span> <span class="token operator">=</span><span class="token operator">&gt;</span> \<span class="token scope">Illuminate<span class="token punctuation">\</span>Routing<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>SubstituteBindings<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token string">'can'</span> <span class="token operator">=</span><span class="token operator">&gt;</span> \<span class="token scope">Illuminate<span class="token punctuation">\</span>Auth<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>Authorize<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token string">'guest'</span> <span class="token operator">=</span><span class="token operator">&gt;</span> \<span class="token scope">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>RedirectIfAuthenticated<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token string">'throttle'</span> <span class="token operator">=</span><span class="token operator">&gt;</span> \<span class="token scope">Illuminate<span class="token punctuation">\</span>Routing<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>ThrottleRequests<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre><p>一旦在 HTTP kernel 文件内定义了中间件,即可使用 <code class=" language-php">middleware</code> 方法将中间件分配给路由:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'admin/profile'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true"> // </span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">middleware<span class="token punctuation">(</span></span><span class="token string">'auth'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>为路由指定多个中间件:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'/'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true"> // </span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">middleware<span class="token punctuation">(</span></span><span class="token string">'first'</span><span class="token punctuation">,</span> <span class="token string">'second'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>也可使用完整类名指定中间件:</p><pre class=" language-php"><code class=" language-php"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>CheckAge</span><span class="token punctuation">;</span> <span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'admin/profile'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true"> // </span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">middleware<span class="token punctuation">(</span></span><span class="token scope">CheckAge<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a name="middleware-groups"></a></p><h3>中间件组</h3><p>有时您可能想要将多个中间件分组到同一个<code class=" language-php">键值</code>下,从而使它们更方便地分配给路由,你可以使用 HTTP kernel 的 <code class=" language-php"><span class="token variable">$middlewareGroups</span></code> 属性来实现。</p><p>Laravel 带有开箱即用的 <code class=" language-php">web</code> 和 <code class=" language-php">api</code> 中间件,包含了可能应用到 Web UI 和 API 路由的通用中间件:</p><pre class=" language-php"><code class=" language-php"><span class="token comment" spellcheck="true">/** * 应用的路由中间件组 * * @var array */</span> <span class="token keyword">protected</span> <span class="token variable">$middlewareGroups</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string">'web'</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token punctuation">[</span> \<span class="token scope">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>EncryptCookies<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span> \<span class="token scope">Illuminate<span class="token punctuation">\</span>Cookie<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>AddQueuedCookiesToResponse<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span> \<span class="token scope">Illuminate<span class="token punctuation">\</span>Session<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>StartSession<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span> \<span class="token scope">Illuminate<span class="token punctuation">\</span>View<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>ShareErrorsFromSession<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span> \<span class="token scope">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>VerifyCsrfToken<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span> \<span class="token scope">Illuminate<span class="token punctuation">\</span>Routing<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>SubstituteBindings<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">'api'</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token punctuation">[</span> <span class="token string">'throttle:60,1'</span><span class="token punctuation">,</span> <span class="token string">'auth:api'</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre><p>中间件组可以像单个中间件一样使用相同的语法指定给路由和控制器。重申,路由组仅仅是为了使一次将多个中间件指定给某个路由的实现变得更加方便。</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'/'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true"> // </span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">middleware<span class="token punctuation">(</span></span><span class="token string">'web'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">group<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token string">'middleware'</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token punctuation">[</span><span class="token string">'web'</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true"> // </span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><blockquote class="has-icon tip"><p><div class="flag"><span class="svg"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" version="1.1" x="0px" y="0px" width="56.6px" height="87.5px" viewBox="0 0 56.6 87.5" enable-background="new 0 0 56.6 87.5" xml:space="preserve"><path fill="#FFFFFF" d="M28.7 64.5c-1.4 0-2.5-1.1-2.5-2.5v-5.7 -5V41c0-1.4 1.1-2.5 2.5-2.5s2.5 1.1 2.5 2.5v10.1 5 5.8C31.2 63.4 30.1 64.5 28.7 64.5zM26.4 0.1C11.9 1 0.3 13.1 0 27.7c-0.1 7.9 3 15.2 8.2 20.4 0.5 0.5 0.8 1 1 1.7l3.1 13.1c0.3 1.1 1.3 1.9 2.4 1.9 0.3 0 0.7-0.1 1.1-0.2 1.1-0.5 1.6-1.8 1.4-3l-2-8.4 -0.4-1.8c-0.7-2.9-2-5.7-4-8 -1-1.2-2-2.5-2.7-3.9C5.8 35.3 4.7 30.3 5.4 25 6.7 14.5 15.2 6.3 25.6 5.1c13.9-1.5 25.8 9.4 25.8 23 0 4.1-1.1 7.9-2.9 11.2 -0.8 1.4-1.7 2.7-2.7 3.9 -2 2.3-3.3 5-4 8L41.4 53l-2 8.4c-0.3 1.2 0.3 2.5 1.4 3 0.3 0.2 0.7 0.2 1.1 0.2 1.1 0 2.2-0.8 2.4-1.9l3.1-13.1c0.2-0.6 0.5-1.2 1-1.7 5-5.1 8.2-12.1 8.2-19.8C56.4 12 42.8-1 26.4 0.1zM43.7 69.6c0 0.5-0.1 0.9-0.3 1.3 -0.4 0.8-0.7 1.6-0.9 2.5 -0.7 3-2 8.6-2 8.6 -1.3 3.2-4.4 5.5-7.9 5.5h-4.1H28h-0.5 -3.6c-3.5 0-6.7-2.4-7.9-5.7l-0.1-0.4 -1.8-7.8c-0.4-1.1-0.8-2.1-1.2-3.1 -0.1-0.3-0.2-0.5-0.2-0.9 0.1-1.3 1.3-2.1 2.6-2.1H41C42.4 67.5 43.6 68.2 43.7 69.6zM37.7 72.5H26.9c-4.2 0-7.2 3.9-6.3 7.9 0.6 1.3 1.8 2.1 3.2 2.1h4.1 0.5 0.5 3.6c1.4 0 2.7-0.8 3.2-2.1L37.7 72.5z"></path></svg></span></div> 开箱即用的 <code class=" language-php">web</code> 中间件组被自动应用于 <code class=" language-php">RouteServiceProvider</code> 中定义的 <code class=" language-php">routes<span class="token operator">/</span>web<span class="token punctuation">.</span>php</code> 路由组。</p></blockquote><p><a name="middleware-parameters"></a></p><h2><a href="#middleware-parameters">中间件参数</a></h2><p>中间件也可以接受其他附加的参数。例如,如果应用需要在运行特定操作前验证该用户具备该操作的权限的「角色」,你可以新建一个 <code class=" language-php">CheckRole</code> 中间件,该中间件接收「角色」名字作为附加参数。</p><p>附加的中间件参数将在 <code class=" language-php"><span class="token variable">$next</span></code> 参数之后被传入:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter">&lt;?php</span> <span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Middleware</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Closure</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">CheckRole</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">/** * 处理传入的请求 * * @param \Illuminate\Http\Request $request * @param \Closure $next * @param string $role * @return mixed */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">handle<span class="token punctuation">(</span></span><span class="token variable">$request</span><span class="token punctuation">,</span> Closure <span class="token variable">$next</span><span class="token punctuation">,</span> <span class="token variable">$role</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span> <span class="token variable">$request</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">user<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">hasRole<span class="token punctuation">(</span></span><span class="token variable">$role</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true"> // Redirect... </span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token variable">$next</span><span class="token punctuation">(</span><span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre><p>定义路由时,指定中间件参数可以通过冒号 <code class=" language-php"><span class="token punctuation">:</span></code> 来隔开中间件与参数,多个参数可以使用逗号分隔:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">put<span class="token punctuation">(</span></span><span class="token string">'post/{id}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true"> // </span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">middleware<span class="token punctuation">(</span></span><span class="token string">'role:editor'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a name="terminable-middleware"></a></p><h2><a href="#terminable-middleware">Terminable 中间件</a></h2><p>有些时候中间件需要在 HTTP 响应发送到浏览器后运行来处理一些任务。比如,Laravel 内置的「session」中间件存储的 session 数据是在响应被发送到浏览器之后才进行写入的。想实现这一点,你需要在中间件中定义一个 <code class=" language-php">terminable</code> 方法,它会在响应发送后自动被调用:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter">&lt;?php</span> <span class="token keyword">namespace</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Session<span class="token punctuation">\</span>Middleware</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Closure</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">StartSession</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">handle<span class="token punctuation">(</span></span><span class="token variable">$request</span><span class="token punctuation">,</span> Closure <span class="token variable">$next</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$next</span><span class="token punctuation">(</span><span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">terminate<span class="token punctuation">(</span></span><span class="token variable">$request</span><span class="token punctuation">,</span> <span class="token variable">$response</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true"> // Store the session data... </span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre><p><code class=" language-php">terminable</code> 方法必需接收请求及响应两个参数。一旦定义了 terminable 中间件,你便需要将它增加到 HTTP kernel 文件的全局中间件清单列表中。</p><p>中间件的 <code class=" language-php">terminate</code> 调用时,Laravel 会从 <a href="/docs/5.4/container">服务容器</a> 中解析一个全新的中间件实例。如果你想在 <code class=" language-php">handle</code> 和 <code class=" language-php">terminate</code> 被调用时使用同一个中间件实例,可使用容器的 <code class=" language-php">singleton</code> 方法向容器注册中间件。</p><h2>译者署名</h2><table><thead><tr><th>用户名</th><th>头像</th><th>职能</th><th>签名</th></tr></thead><tbody><tr><td><a href="http://weibo.com/wangkaibo">@王凯波</a></td><td><img class="avatar-66 rm-style" src="https://dn-phphub.qbox.me/uploads/avatars/1924_1487053084.jpeg?imageView2/1/w/100/h/100"></td><td>翻译</td><td>面向工资编程 😆 <a href="https://github.com/wangkaibo/">@wangkaibo</a></td></tr></tbody></table></article>