
Laravelのミドルウェアで入力項目のデフォルト値を設定する
はじめに
入力項目のデフォルト値を設定するミドルウェアを作ってみました。
実装の一例としてご紹介します。
環境
- PHP v8.0.6
- Laravel v8.45.1
サンプル
ミドルウェアを作成する
プロジェクト直下で以下のコマンドを実行して、ミドルウェアのひな形を作成します。
今回はInputDefaultValueという名前で作成します。
php artisan make:middleware InputDefaultValue
プロジェクト直下/app/Http/Middlewareフォルダに移動します。
フォルダ移動後、作成したInputDefaultValue.phpを以下の通りに修正します。
<?php
namespace App\Http\Middleware;
use Closure;
/**
* Class InputDefaultValue 入力項目のデフォルト値を設定するミドルウェア
*
* @package App\Http\Middleware
*/
class InputDefaultValue
{
private $target;
public function __construct()
{
$this->initInputDefaultTarget();
}
public function handle($request, Closure $next)
{
if (!$this->shouldApplyDefaultValue($request)) return $next($request);
$this->applyDefaultValue($request);
return $next($request);
}
/**
* 入力項目にデフォルト値を設定すべきか判定する
* @param $request
* @return bool
*/
private function shouldApplyDefaultValue($request): bool
{
if ($request->method() === 'GET') return false;
return count($this->getInputDefaultTargets()) > 0;
}
/**
* 現在のURLからターゲットとなる入力項目を取得する
* @return array|mixed
*/
private function getInputDefaultTargets()
{
if (!isset($_SERVER['REQUEST_URI'])) return [];
if (!array_key_exists($_SERVER['REQUEST_URI'], $this->target)) return [];
return $this->target[$_SERVER['REQUEST_URI']];
}
/**
* 入力項目のデフォルト値を設定する
* @param $request
*/
private function applyDefaultValue($request)
{
foreach ($this->getInputDefaultTargets() as $key => $value) {
if ($request->has($key) && !is_null($request->input($key))) continue;
$request->merge([$key => strval($value)]);
}
}
/**
* 入力項目を補完するターゲットを設定する
* ※形式:[パス => [入力項目名 => デフォルト値]]
*/
private function initInputDefaultTarget()
{
$this->target = [
parse_url(route('send'), PHP_URL_PATH) => [
'text' => 'テキスト入力なし',
'checkbox' => 'チェックなし',
],
];
}
}
作成したミドルウェアを有効にする
作成したミドルウェアを有効にするため、設定を追加します。
プロジェクト直下/app/Http/Kernel.phpを開き、$middlewareGroupsのキーがwebの配列に
「\App\Http\Middleware\InputDefaultValue::class」を追加します。
protected $middlewareGroups = [
'web' => [
// 以下を追加
\App\Http\Middleware\InputDefaultValue::class
]
];
コントローラーを作成する
画面表示とデータ送信をハンドリングするコントローラーを作成します。
まず画面表示用のコントローラーを作成するため、プロジェクト直下で以下のコマンドを実行します。
今回はIndexControllerという名前にします。
php artisan make:controller IndexController
プロジェクト直下/app/Http/Controllersに移動します。
フォルダ移動後、作成したコントローラーを以下の通りに修正します。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
/**
* Class IndexController
* @package App\Http\Controllers\Index
*/
class IndexController extends Controller
{
public function __invoke(Request $request)
{
return view('index');
}
}
次にデータ送信用のコントローラー作成するため、プロジェクト直下で以下のコマンドを実行します。
今回はPostControllerという名前にします。
php artisan make:controller PostController
プロジェクト直下/app/Http/Controllersに移動します。
フォルダ移動後、作成したコントローラーを以下の通りに修正します。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
/**
* Class PostController
* @package App\Http\Controllers\Index
*/
class PostController extends Controller
{
public function __invoke(Request $request)
{
//デフォルト値確認用ログ
Log::debug($request->all());
return redirect()->route('index');
}
}
ルーティングの定義を追加する
リクエストをハンドリングするため、設定を追加します。
プロジェクト直下/routes/web.phpを開き、以下の定義を追加します。
Route::get('index', \App\Http\Controllers\IndexController::class)->name('index');
Route::post('send', \App\Http\Controllers\PostController::class)->name('send');
ビューを作成する
プロジェクト直下/resources/views内にindex.blade.phpを作成し、以下の通りに修正します。
<!doctype html>
<html lang="ja">
<head>
<title>サンプル</title>
</head>
<body>
<form action="{{route('send')}}" method="post">
@csrf
<input type="text" name="text">
<input type="checkbox" name="checkbox" value="チェックあり">
<input type="submit" value="送信">
</form>
</body>
</html>
動作確認
開発用サーバを起動するため、プロジェクト直下で以下のコマンドを実行します。
php artisan serve
サーバ起動後、http://localhost:8000/index にアクセスします。
表示された画面で何も入力せず、送信ボタンを押下します。
送信ボタン押下後、プロジェクト直下/storage/logs内にあるログを開くと、
ミドルウェアで指定したデフォルト値が設定されていることが確認できます。
[2021-06-07 10:22:08] local.DEBUG: array ( '_token' => '2gba19krMyLcpOYLC2lHHUi5gGO9WD9VeNPkj00N', 'text' => 'テキスト入力なし', 'checkbox' => 'チェックなし', )
まとめ
以上がLaravelのミドルウェアで入力項目のデフォルト値を設定する一例でした。
使いどころとしては単純に入力がないときにデフォルト値を設定したい場合や、
チェックボックスにチェックがない場合に(リクエストにデータが含まれないため)、
デフォルト値を設定するような使い方ができるかと思います。
実装の一例として参考になりましたら幸いです。