はじめに
Webサイトやシステムを作る際、何かしらの入力フォームを用意するケースは多々あると思います。
そして、そのフォームで入力された情報が不適切な場合、入力者にその旨を伝える必要があります。
本記事では、それらを実現するためのフォーム作成およびバリデーションの設定方法をまとめます。
本記事で行うこと
- Formファサードを活用した入力フォームの作成
- バリデーションの設定
- バリデーションエラーメッセージの日本語化
- バリデーションエラーメッセージを日本語にして画面表示
開発環境・前提
開発環境
- OS:Windows11 22H2
- PHP 8.2.4
- Laravel 9.44.0
前提
- ローカルにLaravel開発環境があり、開発サーバーを起動済みであること。
- 各ファイル・ルート・メソッド名は任意。
- デザインは特に考慮せず、機能・動作の確認のみ実施。
- DBへのデータ保存は行わず、機能・動作の確認のみ実施。
手順
1. 入力フォーム作成で「Formファサード」を用いるため、以下のコマンドでLaravel Collective
パッケージをインストール。
composer require laravelcollective/html
(参考:Laravel Collectiveの公式サイトおよびGitHub)
2. 以下のコマンドで、app/Http/Requests/
にリクエストァイルを作成(今回の例ではCreateMessageRequest.php
)。
php artisan make:request CreateMessageRequest
3. routes
ディレクトリのweb.php
でルーティングを編集。
Route::get('message', [App\Http\Controllers\MessageController::class, 'index']);
Route::post('message', [App\Http\Controllers\MessageController::class, 'post']->name('postMessage');
4. 作成したリクエストファイルを編集。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreateMessageRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
- return false;
+ return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, mixed>
*/
public function rules()
{
return [
+ 'message' => 'required',
];
}
}
5. app/Http/Controllers/
にコントローラーを作成・編集(今回の例ではMessageController.php
)。
<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
use App\Http\Requests\CreateMessageRequest;
class MessageController extends BaseController
{
public function index()
{
return view('message');
}
public function post(CreateMessageRequest $request)
{
$input = $request->validated();
return view('message')->with('inputMessage', $input);
}
}
6. resources/views/
にbladeファイルを作成(今回の例ではmessage.blade.php
)& bodyタグ内に以下を追記。
<!-- 該当部分を抜粋 -->
<body>
@if ($errors->any())
<div>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
{{ Form::open(['route' => 'postMessage']) }}
{{ Form::label('message', 'タイトル:') }}
{{ Form::text('message', null) }}
{{ Form::submit('送信') }}
{{ Form::close() }}
@if (isset($inputMessage))
<p>送信したメッセージ:{{ $inputMessage['message'] }}</p>
@endif
</body>
また、ブラウザで確認しやすいよう背景色を調整するために、styleタグ内に以下を追記。
<!-- 該当部分を抜粋 -->
<style>
body {
font-family: 'Nunito', sans-serif;
+ background-color: #eee;
}
</style>
7. 以下のコマンドを順番に入力し、resources/lang/ja/
にvalidation.php
を作成。
php -r "copy('https://readouble.com/laravel/8.x/ja/install-ja-lang-files.php', 'install-ja-lang.php');"
php -f install-ja-lang.php
php -r "unlink('install-ja-lang.php');"
(参考:Laravel公式サイト)
8. config
ディレクトリのapp.php
にて、以下の部分を編集。
// 該当部分を抜粋
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
- 'timezone' => 'UTC',
+ 'timezone' => 'Asia/Tokyo',
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
- 'locale' => 'en',
+ 'locale' => 'ja',
9. 作成したvalidation.php
の「カスタムバリデーション属性名」の欄にて、日本語化用に以下の通り追記。
/*
|--------------------------------------------------------------------------
| カスタムバリデーション属性名
|--------------------------------------------------------------------------
|
| 以下の言語行は、例えば"email"の代わりに「メールアドレス」のように、
| 読み手にフレンドリーな表現でプレースホルダーを置き換えるために指定する
| 言語行です。これはメッセージをよりきれいに表示するために役に立ちます。
|
*/
'attributes' => [
+ 'message' => 'メッセージ',
],
10. http://localhost/message
に接続し、ブラウザで確認。
フォームに何も入力せずに「送信」を押下すると、次の画像の通りエラーメッセージが表示。
ポイントの解説
Formファサードの導入(手順1)
Formファサードを活用すれば、入力フォーム作成を簡潔に行うことができます。
記述量の差はあまりないかもしれませんが、いちいちタグで閉じたり、POST・PUT・DELETE処理時のCSRF対策用トークン設置の記述をせずに済みます。
入力数の多いフォームだと、より効果を発揮すると思います。
<!-- 該当部分を抜粋 -->
<!-- Formファサードを使わない場合 -->
<form method="POST" action="{{ route('postMessage') }}" accept-charset="UTF-8">
@csrf
<label for="message">メッセージ:</label>
<input name="message" type="text" id="message">
<input type="submit" value="送信">
</form>
<!-- Formファサードを使う場合 -->
{{ Form::open(['route' => 'postMessage']) }}
{{ Form::label('message', 'メッセージ:') }}
{{ Form::text('message', null) }}
{{ Form::submit('送信') }}
{{ Form::close() }}
ルーティング(手順3)
->name('postMessage')
で名前付きルートにし、bladeファイルでルートを指定しやすくしています。
リクエスト(手順4)
- authorizeメソッドでfalseが返却されると403エラーになるので、trueに変更しています。
これで常にリクエストが認可され、コントローラーに記載のメソッドが実行されます。 - rulesメソッドでバリデーションを定義します。
今回はmessageに対してrequired
のみ適用しています。
コントローラー(手順5)
-
use App\Http\Requests\CreateMessageRequest;
の記述で、前の手順で作成したCreateMessageRequest
が使用可能になります。 - indexメソッドで画面表示を実行しています。
- postメソッドでテキスト送信および画面表示を実行しています。
①$input = $request->validated()
では、CreateMessageRequest
で定義したバリデーションを通過した入力値が変数$input
に格納されます。
②withメソッドで変数$input
をビューに渡しています。
ビュー(blade)(手順6)
-
$erros->any()
では、エラーがある場合はtrueが返却されるので、@if ($errors->any()) ~ @endif
までの内容はエラー時のみ表示されます。 -
@foreach ~ @endforeach
で、全てのエラーメッセージを1つずつ取り出してリスト表示しています。
今回はバリデーションを1つだけ定義しているので、表示されるエラーメッセージも1つです。 -
@if (isset($inputMessage)) ~ @endif
の部分で、入力内容が正常に送信されたら、その内容を画面に表示するようにしています。
バリデーションエラーメッセージの日本語化(手順7~10)
バリデーションエラーメッセージ用ファイルを作成の上、日本語化の設定を行っています。
今回はmessage入力欄だけを用意したので、エラーメッセージの日本語化もmessageのみです。
なお、次のようにCreateMessageRequest.php
に他のバリデーションも加え、それに該当する誤った入力をすると、以下の画像のように表示されます。
// 該当部分を抜粋
public function rules()
{
return [
'message' => 'required|integer|max:10',
];
}
messageに対してrequired
の他にinterger
とmax:10
を追記することで、「入力値必須」かつ「整数で10以下の数字」のみを受け付ける状態になります。
試しに数字の「3」を入力・送信すると、正常に処理されます。
(数値は半角)
required
・interger
・max
に関するバリデーションエラーメッセージは、デフォルトでresources/lang/ja/validation.php
に以下のように記述されているため、そのまま日本語化されます。
なお、今回のattributeは「message」であり、手順9で「メッセージ」と日本語に変換しています。
// 該当部分をそれぞれ抜粋
'integer' => ':attributeは整数で指定してください。',
'max' => [
'numeric' => ':attributeには、:max以下の数字を指定してください。',
'file' => ':attributeには、:max kB以下のファイルを指定してください。',
'string' => ':attributeは、:max文字以下で指定してください。',
'array' => ':attributeは:max個以下指定してください。',
],
'required' => ':attributeは必ず指定してください。',
また、他にもbetween
・boolean
・string
などもよく使います。
// 該当部分をそれぞれ抜粋
'between' => [
'numeric' => ':attributeは、:minから:maxの間で指定してください。',
'file' => ':attributeは、:min kBから、:max kBの間で指定してください。',
'string' => ':attributeは、:min文字から、:max文字の間で指定してください。',
'array' => ':attributeは、:min個から:max個の間で指定してください。',
],
'boolean' => ':attributeは、trueかfalseを指定してください。',
'string' => ':attributeは文字列を指定してください。',
(例1)CreateMessageRequest.php
でbetween
を指定した場合(integer
と組み合わせてnumeric
扱いにし、整数1~9を指定)
// 該当部分を抜粋
public function rules()
{
return [
- 'message' => 'required|integer|max:10',
+ 'message' => 'integer|between:1,9',
];
}
(数値は半角)
(例2)CreateMessageRequest.php
でboolean
を指定した場合
// 該当部分を抜粋
public function rules()
{
return [
- 'message' => 'required|integer|max:10',
+ 'message' => 'boolean',
];
}
(true=1、false=0)
(例3)CreateMessageRequest.php
でstring
を指定した場合
// 該当部分を抜粋
public function rules()
{
return [
- 'message' => 'required|integer|max:10',
+ 'message' => 'string',
];
}
(補足)フォームでも入力値必須の設定
これまでの手順ではPHP/Laravel側で入力値必須の設定を行いましたが、ビュー(blade)でHTMLの記述を行うことで、フォーム自体に設定することもできます。
以下の通りbladeファイルのフォーム部分にrequired
属性を付与すると、未入力送信時に画像のようなエラーメッセージが表示されます。
このようにバリデーションと併せてフォーム自体の設定もしておくと、意図しないデータの入力・送信をより確実に防ぐことができます。
<!-- 該当部分を抜粋 -->
{{ Form::open(['route' => 'postMessage']) }}
{{ Form::label('message', 'メッセージ:') }}
- {{ Form::text('message', null) }}
+ {{ Form::text('message', null, ['required']) }}
<!-- <input required name="message" type="text" id="message">と同様 -->
{{ Form::submit('送信') }}
{{ Form::close() }}
まとめ
入力フォーム作成とバリデーションの設定は、開発業務では頻出事項だと思います。
今回はデザインを考慮しませんでしたが、ユーザーの分かりやすさ・使いやすさを追求すると、さらに考えるべき点が出てくるので奥深いです。
なお、基本さえ押さえれば実装自体はそこまで難しくないので、ぜひ慣れておきましょう!
本記事が少しでも読者の皆様の参考になれば幸いです。
それでは良き開発ライフを!!
参考情報
Laravel公式