Laravel 5.4: 如何通过中间件将模型对象传递给控制器?
Laravel 5.4: how to pass model object to controller via middleware?
我正在 Laravel 5.4 中创建一个应用程序,其中我有一个中间件 ValidateBooking
,然后是一个用 URL 调用的控制器,例如 /booking/6/car
,它列出了所有分配给该预订的汽车。
在 ValidateBooking
中间件中,我使用 Booking::find(6)
Eloquent 函数验证上述 URL 中的预订 ID 6
。但我想要的是,如果 Booking 存在,则将该对象传递给控制器,这样我就不会在控制器中再次获取它。我不想为同一件事查询数据库两次。
我尝试了几种方法将模型对象与中间件中的 $request
合并,但无法在控制器中正确访问它。
我的中间件代码是:
<?php
namespace App\Http\Middleware\Booking;
use Closure;
use App\Booking\Booking;
class ValidateBooking
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$booking = Booking::find($request->booking_id);
if (!$booking) {
return redirect(route('booking.show', $request->booking_id));
}
$request->attributes->add(['bookingInstance' => $booking]);
return $next($request);
}
}
然后在控制器中获取它,如:
$request->get('bookingInstance')
如果我传递任何字符串值或其他东西,但不是对象,它会起作用吗?请告知最好的方法是什么。
这是您可以执行的操作。我遇到过一次这个问题。
public function handle($request, Closure $next)
{
$booking = Booking::find($request->booking_id);
if (!$booking) {
return redirect(route('booking.show', $request->booking_id));
}
sesion()->put('bookingInstance', $booking);
return $next($request);
}
这很简单。
您只能对请求对象使用 merge()
函数。
public function handle($request, Closure $next)
{
$booking = Booking::find($request->booking_id);
if (!$booking) {
return redirect(route('booking.show', $request->booking_id));
}
$request->merge(['bookingInstance' => $booking]);
return $next($request);
}
除了使用被证明有效的 $request->merge()
之外,只需将模型对象添加到请求中,使用以下内容也可以帮助您在控制器中访问模型:
$request->booking = $booking;
唯一需要注意的是确保没有名为 booking 的参数,以免覆盖它。
我想你想看的是Explicit Route Model bindings。
如果您向 RouteServiceProvider
添加显式绑定,则可以在中间件和控制器中访问该参数。
// app/Providers/RouteServiceProvider.php
public function boot()
{
parent::boot();
Route::model('booking', \App\Booking\Booking::class);
}
// routes/web.php
Route::get('/booking/{booking}/car', 'BookingController@car')->middleware('booking.validate');
// app/Http/Middleware/ValidateBooking.php
public function handle($request, Closure $next)
{
$booking = $request->booking;
// ...
return $next($request);
}
// app/Http/Controllers/BookingController.php
public function car(Request $request)
{
dd($request->booking);
}
我正在 Laravel 5.4 中创建一个应用程序,其中我有一个中间件 ValidateBooking
,然后是一个用 URL 调用的控制器,例如 /booking/6/car
,它列出了所有分配给该预订的汽车。
在 ValidateBooking
中间件中,我使用 Booking::find(6)
Eloquent 函数验证上述 URL 中的预订 ID 6
。但我想要的是,如果 Booking 存在,则将该对象传递给控制器,这样我就不会在控制器中再次获取它。我不想为同一件事查询数据库两次。
我尝试了几种方法将模型对象与中间件中的 $request
合并,但无法在控制器中正确访问它。
我的中间件代码是:
<?php
namespace App\Http\Middleware\Booking;
use Closure;
use App\Booking\Booking;
class ValidateBooking
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$booking = Booking::find($request->booking_id);
if (!$booking) {
return redirect(route('booking.show', $request->booking_id));
}
$request->attributes->add(['bookingInstance' => $booking]);
return $next($request);
}
}
然后在控制器中获取它,如:
$request->get('bookingInstance')
如果我传递任何字符串值或其他东西,但不是对象,它会起作用吗?请告知最好的方法是什么。
这是您可以执行的操作。我遇到过一次这个问题。
public function handle($request, Closure $next)
{
$booking = Booking::find($request->booking_id);
if (!$booking) {
return redirect(route('booking.show', $request->booking_id));
}
sesion()->put('bookingInstance', $booking);
return $next($request);
}
这很简单。
您只能对请求对象使用 merge()
函数。
public function handle($request, Closure $next)
{
$booking = Booking::find($request->booking_id);
if (!$booking) {
return redirect(route('booking.show', $request->booking_id));
}
$request->merge(['bookingInstance' => $booking]);
return $next($request);
}
除了使用被证明有效的 $request->merge()
之外,只需将模型对象添加到请求中,使用以下内容也可以帮助您在控制器中访问模型:
$request->booking = $booking;
唯一需要注意的是确保没有名为 booking 的参数,以免覆盖它。
我想你想看的是Explicit Route Model bindings。
如果您向 RouteServiceProvider
添加显式绑定,则可以在中间件和控制器中访问该参数。
// app/Providers/RouteServiceProvider.php
public function boot()
{
parent::boot();
Route::model('booking', \App\Booking\Booking::class);
}
// routes/web.php
Route::get('/booking/{booking}/car', 'BookingController@car')->middleware('booking.validate');
// app/Http/Middleware/ValidateBooking.php
public function handle($request, Closure $next)
{
$booking = $request->booking;
// ...
return $next($request);
}
// app/Http/Controllers/BookingController.php
public function car(Request $request)
{
dd($request->booking);
}