LoginSignup
2

【PHP/Laravel】Formファサードで入力フォーム作成&バリデーション設定&日本語化

Last updated at Posted at 2023-05-26

はじめに

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でルーティングを編集。
web.php
Route::get('message', [App\Http\Controllers\MessageController::class, 'index']);
Route::post('message', [App\Http\Controllers\MessageController::class, 'post']->name('postMessage');
4. 作成したリクエストファイルを編集。
CreateMessageRequest.php
<?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)。
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タグ内に以下を追記。
mesage.blade.php
<!-- 該当部分を抜粋 -->
<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タグ内に以下を追記。

mesage.blade.php
<!-- 該当部分を抜粋 -->
<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にて、以下の部分を編集。
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の「カスタムバリデーション属性名」の欄にて、日本語化用に以下の通り追記。
validation.php
/*
|--------------------------------------------------------------------------
| カスタムバリデーション属性名
|--------------------------------------------------------------------------
|
| 以下の言語行は、例えば"email"の代わりに「メールアドレス」のように、
| 読み手にフレンドリーな表現でプレースホルダーを置き換えるために指定する
| 言語行です。これはメッセージをよりきれいに表示するために役に立ちます。
|
*/

'attributes' => [
+   'message' => 'メッセージ',
],
10. http://localhost/messageに接続し、ブラウザで確認。

  フォームに何も入力せずに「送信」を押下すると、次の画像の通りエラーメッセージが表示。
タイトル入力フォーム_requiredバリデーション_日本語化2.png

ポイントの解説

Formファサードの導入(手順1

Formファサードを活用すれば、入力フォーム作成を簡潔に行うことができます。
記述量の差はあまりないかもしれませんが、いちいちタグで閉じたり、POST・PUT・DELETE処理時のCSRF対策用トークン設置の記述をせずに済みます。
入力数の多いフォームだと、より効果を発揮すると思います。

message.blade.php
<!-- 該当部分を抜粋 -->
<!-- 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に他のバリデーションも加え、それに該当する誤った入力をすると、以下の画像のように表示されます。

CreateMessageRequest.php
// 該当部分を抜粋
public function rules()
{
    return [
        'message' => 'required|integer|max:10',
    ];
}

タイトル入力フォーム_requiredバリデーション_日本語化3.png
messageに対してrequiredの他にintergermax:10を追記することで、「入力値必須」かつ「整数で10以下の数字」のみを受け付ける状態になります。

試しに数字の「3」を入力・送信すると、正常に処理されます。

(数値は半角)
タイトル入力フォーム_requiredバリデーション_日本語化4.png
requiredintergermaxに関するバリデーションエラーメッセージは、デフォルトでresources/lang/ja/validation.phpに以下のように記述されているため、そのまま日本語化されます。
なお、今回のattributeは「message」であり、手順9で「メッセージ」と日本語に変換しています。

validation.php
// 該当部分をそれぞれ抜粋
'integer'              => ':attributeは整数で指定してください。',

'max'                  => [
    'numeric' => ':attributeには、:max以下の数字を指定してください。',
    'file'    => ':attributeには、:max kB以下のファイルを指定してください。',
    'string'  => ':attributeは、:max文字以下で指定してください。',
    'array'   => ':attributeは:max個以下指定してください。',
],

'required'             => ':attributeは必ず指定してください。',

また、他にもbetweenbooleanstringなどもよく使います。

validation.php
// 該当部分をそれぞれ抜粋
'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.phpbetweenを指定した場合(integerと組み合わせてnumeric扱いにし、整数1~9を指定)

CreateMessageRequest.php
// 該当部分を抜粋
public function rules()
{
    return [
-        'message' => 'required|integer|max:10',
+        'message' => 'integer|between:1,9',
    ];
}

(数値は半角)
タイトル入力フォーム_requiredバリデーション_日本語化_例2_1.png
(例2)CreateMessageRequest.phpbooleanを指定した場合

CreateMessageRequest.php
// 該当部分を抜粋
public function rules()
{
    return [
-        'message' => 'required|integer|max:10',
+        'message' => 'boolean',
    ];
}

(true=1、false=0)
タイトル入力フォーム_requiredバリデーション_日本語化_例1.png
(例3)CreateMessageRequest.phpstringを指定した場合

CreateMessageRequest.php
// 該当部分を抜粋
public function rules()
{
    return [
-        'message' => 'required|integer|max:10',
+        'message' => 'string',
    ];
}

(何も入力せずに送信)
タイトル入力フォーム_requiredバリデーション_日本語化_例2_3.png

(補足)フォームでも入力値必須の設定

これまでの手順ではPHP/Laravel側で入力値必須の設定を行いましたが、ビュー(blade)でHTMLの記述を行うことで、フォーム自体に設定することもできます。
以下の通りbladeファイルのフォーム部分にrequired属性を付与すると、未入力送信時に画像のようなエラーメッセージが表示されます。
このようにバリデーションと併せてフォーム自体の設定もしておくと、意図しないデータの入力・送信をより確実に防ぐことができます。

message.blade.php
<!-- 該当部分を抜粋 -->
{{ 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() }}

タイトル入力フォーム_requiredバリデーション_補足.png

まとめ

入力フォーム作成とバリデーションの設定は、開発業務では頻出事項だと思います。
今回はデザインを考慮しませんでしたが、ユーザーの分かりやすさ・使いやすさを追求すると、さらに考えるべき点が出てくるので奥深いです。
なお、基本さえ押さえれば実装自体はそこまで難しくないので、ぜひ慣れておきましょう!

本記事が少しでも読者の皆様の参考になれば幸いです。

それでは良き開発ライフを!!

参考情報

Laravel公式

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2