自作ミドルウェアの中で、ルートパラメータを取得してEloquentでfind
して・・・、みたいな事をしていた時に気づいた事を書いておきます。
環境
- php7.3
- laravel5.8
補足
- ミドルウェアは
Kernel.php
の$routeMiddleware
に追加する - 結果は経験則なので理由を調べたわけではない(すみません)
ルーティング
ルーティングでミドルウェアを適用します。
web.php
Route::get('/users/{user}', 'UserController@detail')->middleware('user.open');
ミドルウェアの登録
カーネルで自作ミドルウェアを登録します。
/project/app/Http/Kernel.php
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'user.open' => \App\Http\Middleware\UserOpenMiddleware::class, //これを追加
];
ミドルウェアを作成
UserOpenMiddleware.php
class UserOpenMiddleware
{
public function handle($request, Closure $next)
{
$param = $request->route()->parameter('user');
/**
* $paramの値はどっち??
*/
$userModel = User::findOrFail($param); //10?
$userModel = $param; //Userモデルのオブジェクト?
//取得したモデルを使って色々ロジックを書く・・・・
if($userModel->open){
}
return $next($request);
}
}
さて、本題です。
ここでhttp://ドメイン/users/10
にアクセスした時、ミドルウェアの最初の行で取得した$param
変数は10
なのか、それともUser
モデルのオブジェクトなのか・・・?
実は、これだけじゃ判断できないんです。
ここからは経験則なので、ちゃんと調べたわけじゃないんですが、、、
コントローラーがどうなっているかによって$param
の値は変わります。
コントローラ
(暗黙の)モデル結合ルートを使う場合
UserController.php
class UserController extends Controller
{
public function detail(Request $request, User $user){
//ごにょごにょ・・・
return view('pages.user.detail');
}
コントローラーの引数にUser
型をタイプヒントした$user
変数がいた場合は、Larvelが自動的にid=10のUser
モデルを注入してくれます。
この場合、ミドルウェアの$param
もUser
モデルのオブジェクトになります。
ポイントはルートパラメータ名{user}
と変数名$user
を合わせる事。
モデル結合ルートを使わない場合
UserController.php
class UserController extends Controller
{
public function detail(Request $request){
//ごにょごにょ・・・
return view('pages.user.detail');
}
この場合だと、ミドルウェアの$param
は10
になります。
結果
UserOpenMiddleware.php
class UserOpenMiddleware
{
public function handle($request, Closure $next)
{
$param = $request->route()->parameter('user');
/**
* $paramの値はどっち??
*/
//コントローラーがモデル結合じゃない場合
//$param = 10
$userModel = User::findOrFail($param);
//コントローラーがモデル結合の場合
//Userモデルのオブジェクト
$userModel = $param;
//取得したモデルを使って色々ロジックを書く・・・・
if($userModel->open){
}
return $next($request);
}
}