やりたいこと
ユーザーのログイン回数や資料ダウンロード回数などを取得したい。
つまり、特定のアクションメソッドを通ったら、そのアクションタイプを書き込みたい。
流れ
- Middlewareを作成する。
- 後処理として、特定のアクションをDBに書き込む処理を書く
- kernelに登録する
LaravelのMiddlewareとは(簡単に)
Controllerで行われる処理の前や後に、処理を追加することができる機能?です。
デフォルトで組み込まれているためあまり意識することがないですが、
トークンやセッションの管理などはmiddlewareで処理されています。
実装
Middlewareを作成する。
以下のコマンドで、Middlewareディレクトリ配下にLogActions.phpが作られます。
php artisan make:middleware LogActions
後処理として、特定のアクションをDBに書き込む処理を書く
作成されたファイルには、handleメソッドがあるので、ここに処理を書いていきます。
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
return $next($request);
}
$next($request)
よりも前が前処理、後ろが後処理になります。
今回は、後処理を追加したいため、$next($request)
を変数$response
に格納し、
書き込み処理を行なった後に$response
を返却します。
なお、今回の処理は簡単なものだったため、メソッドに全て処理を記載しましたが、
プロパティやメソッドを呼んだり、クラスをインジェクションすることも当然可能です。
public function handle($request, Closure $next)
{
// レスポンスを格納
$response = $next($request);
// アクション名を取得
$action = $request->route()->getActionName();
// DBに書き込むアクションの配列
$actions = [
// ログイン
'login' => 'App\Http\Controllers\Auth\LoginController@login',
// 閲覧
'show' => 'App\Http\Controllers\TestController@show',
// ダウンロード
'download' => 'App\Http\Controllers\TestController@download',
];
// 書き込み処理
if (in_array($action, $actions)) {
DB::table('log_actions')->insert([
'user_id' => Auth::user()->id,
'action_type' => array_search($action, $actions),
'created_at' => now(),
'updated_at' => now(),
]);
}
// レスポンスを返す。
return $response;
}
kernelに登録する
最後にApp/Http/Kernel.phpに作成したMiddlewareを登録します。
今回は普通のwebアプリケーションのため$middlewareGroups
のwebグループの一番最後に追加しました。
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\LogTraderActions::class // !!!追加!!!
],
'api' => [
'throttle:60,1',
'bindings',
],
];
これで、アクションログを書き込むことができるようになりました。
処理が重たくなる場合には、キューを使って非同期処理を行う方が良いと思います。