5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【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公式

5
3
0

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
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?