在本文中,我们将深入研究Laravel框架,以了解中间件的概念。 本文的前半部分首先介绍了中间件及其实际用途。
在继续学习时,我们将介绍如何在Laravel应用程序中创建自定义中间件。 创建自定义中间件之后,我们将探索可用于向Laravel注册它的选项,以便可以在请求处理流程中实际调用它。
我希望您认为自己熟悉Laravel的基本概念和Artisan命令行工具来生成脚手架代码。 当然,最新的Laravel应用程序的有效安装可以使您直接运行本文中提供的示例。
Laravel中的中间件是什么?
我们可以将中间件视为一种机制,使您可以参与Laravel应用程序的典型请求处理流程。 典型的Laravel路由处理经历请求处理的某些阶段,而中间件是应用程序必须经过的那些层之一。
那么,钩入Laravel请求处理流程的确切目的是什么? 考虑一些需要在应用程序引导的早期阶段执行的事情。 例如,有必要在早期对用户进行身份验证,以决定是否允许他们访问当前路由。
我想到的一些可以通过中间件实现的功能是:
- 记录请求
- 重定向用户
- 更改/消毒传入的参数
- 处理Laravel应用程序生成的响应
- 还有很多
实际上,默认的Laravel应用程序已经附带了几个重要的中间件。 例如,有一个中间件检查站点是否处于维护模式。 另一方面,有中间件可以清理输入请求参数。 如前所述,用户身份验证也可以通过中间件本身来实现。
我希望到目前为止的解释可以帮助您对术语“中间件”更加自信。 如果您仍然感到困惑,请不要担心,因为我们将从下一节开始构建一个自定义中间件,这将帮助您准确了解如何在现实世界中使用中间件。
如何创建自定义中间件
在本节中,我们将创建我们的自定义中间件。 但是我们的定制中间件到底要完成什么呢?
最近,我遇到了一个来自客户的自定义要求,即如果用户从任何移动设备访问该站点,则应将其重定向到相应的子域URL,同时保留所有querystring参数。 我相信这是完美的用例,以演示如何在这种特定情况下使用Laravel中间件。
我们想在这种情况下使用中间件的原因是需要挂接到应用程序的请求流中。 在我们的自定义中间件中,我们将检查用户代理,如果用户使用的是移动设备,则会将他们重定向到相应的移动URL。
讨论了所有理论之后,让我们进入实际开发,这是理解新概念的最佳方法,不是吗?
作为Laravel开发人员,如果您希望创建任何自定义功能,那么最终将使用Artisan工具来创建基本模板代码。 让我们用它为我们的自定义中间件创建基本的模板代码。
转至命令行,然后进入项目的文档根目录。 运行以下命令以创建自定义中间件模板MobileRedirect
。
php artisan make:middleware MobileRedirect
然后,应使用以下代码创建文件app/Http/Middleware/MobileRedirect.php
。
<?php
namespace App\Http\Middleware;
use Closure;
class MobileRedirect
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
return $next($request);
}
}
通常,您会注意到充当中间件主干的handle
方法的实现,而您打算实现的中间件的主要逻辑应该放在这里。
让我抓住这个机会介绍Laravel随附的中间件的类型。 主要有两种类型-中间件之前和之后。
顾名思义,before中间件是在实际处理请求和构建响应之前运行的。 另一方面,after中间件在应用程序处理了请求并在此时已建立响应之后运行。
在我们的例子中,我们需要在处理请求之前重定向用户,因此它将被开发为之前的中间件。
继续并使用以下内容修改文件app/Http/Middleware/MobileRedirect.php
。
<?php
namespace App\Http\Middleware;
use Closure;
class MobileRedirect
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// check if the request is from mobile device
if ($request->mobile == "1") {
return redirect('mobile-site-url-goes-here');
}
return $next($request);
}
}
为简单起见,我们仅检查mobile
querystring参数的存在,如果将其设置为TRUE
,则用户将被重定向到相应的移动站点URL。 当然,如果您希望实时检测它,则希望使用用户代理检测库。
另外,您还想用正确的路由或URL替换mobile-site-url-goes-here
路由,因为它只是一个用于演示目的的占位符。
按照我们的自定义逻辑,对$next($request)
了调用,该调用允许在应用程序链中进一步处理请求。 在我们的案例中要注意的重要一点是,我们已将移动检测逻辑放在$next($request)
调用之前,实际上使它成为了中间件之前的产品。
这样,我们的自定义中间件几乎可以进行测试了。 目前,Laravel无法了解我们的中间件。 为此,您需要在Laravel应用程序中注册中间件,而这正是我们下一节的主题。
在进入下一部分之前,我想演示一下中间件的外观,以防万一有人对它感到好奇。
<?php
namespace App\Http\Middleware;
use Closure;
class CustomMiddleWare
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
/* your custom logic goes here */
return $response;
}
}
正如您已经注意到的那样,在Laravel应用程序处理了请求之后,将执行中间件的自定义逻辑。 此时,您还可以访问$response
对象,如果需要,您可以使用它来操纵它的某些方面。
这就是中间件的故事。
我们的定制中间件在行动
本节描述了向Laravel应用程序注册中间件的过程,以便可以在请求处理流程中实际调用该中间件。
继续打开文件app/Http/Kernel.php
并查找以下代码段。
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
如您所见, $middleware
包含Laravel默认安装随附的一系列中间件。 此处列出的中间件将在每个Laravel请求时执行,因此它是放置我们自己的自定义中间件的理想选择。
继续并包含我们的自定义中间件,如以下代码片段所示。
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\MobileRedirect::class,
];
现在,尝试使用querystring mobile=1
来访问您的任何Laravel路由,这将触发我们的中间件代码!
这样便可以注册需要在每个请求上运行的中间件。 但是,有时您只希望针对特定路由运行中间件。 让我们检查如何通过使用$routeMiddleware
实现这$routeMiddleware
。
在当前示例的上下文中,假设用户访问您网站上的任何特定路由,都将被重定向到移动网站。 在这种情况下,您不想将中间件包括在$middleware
列表中。
相反,您希望将中间件直接附加到路由定义,如下所示。
Route::get('/hello-world', 'HelloWorldController@index')->middleware(\App\Http\Middleware\MobileRedirect::class);
实际上,我们可以更进一步,为我们的中间件创建一个别名,这样您就不必使用内联类名。
打开文件app/Http/Kernel.php
并查找用于保存别名到中间件的映射的$routeMiddleware
。 让我们将我们的条目包含在该列表中,如以下代码片段所示。
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'mobile.redirect' => \App\Http\Middleware\MobileRedirect::class
];
修改后的路线定义如下所示。
Route::get('/hello-world', 'HelloWorldController@index')->middleware('mobile.redirect');
这就是使用Laravel应用程序注册中间件的故事。 那很简单,不是吗?
实际上,我们已经到了本文的结尾,我希望您彻底喜欢它。
结论
在任何框架中探索架构概念总是令人兴奋的事情,这就是我们在Laravel框架中探索中间件时所做的。
从对中间件的基本介绍开始,我们将注意力转移到在Laravel应用程序中创建自定义中间件的主题。 文章的后半部分讨论了如何在Laravel中注册自定义中间件,这也是探索连接中间件的不同方式的机会。
希望这次旅程是富有成果的,这篇文章可以帮助您丰富知识。 另外,如果您希望我在以后的文章中提出特定的主题,则可以随时给我留言。
今天就这样,不要犹豫,使用下面的提要来记录您的查询!
翻译自: https://code.tutsplus.com/tutorials/understand-the-basics-of-laravel-middleware--cms-29147