0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Laravel バリデーションエラーメモ

Posted at

見る前の注意書き

フォームのバリデーションエラーメッセージを扱う際に
その都度よく検索している気がするので自分用にまとめたものです

そんなの知ってるよ!という人はブラウザバックのお土産にクッキーをどうぞ:cookie:

Laravel 10・11にて動作確認しました
バージョンが異なる場合は
実装方法に変更の可能性がありますのでご留意ください

requestファイルを作る

Controllerにてバリデーションルールを処理することは可能だが、管理しやすくするため
バリデーションルール用のクラスを用意する

app\Http\Requestsフォルダ下にRequestクラスのファイルを作成する

ターミナルで以下実行
php artisan make:request クラス名

requestクラスは以下例のようにルールをまとめて書けるのでとても便利

requestファイル 記載例
class クラス名 extends FormRequest
{
    public function authorize(): bool
    {
        return true; // falseからtrueに変更する
    }
        
    public function rules(): array
    {
    // リクエストデータ内容を参照したい場合
    $data = $this->all();

        // バリデーションルール設定
        $rule = [
            'name' => [
                'required',
                'max: 255'
            ],
            'name.*' => [ // 同じnameが複数あり、まとめて指定する場合 .*を付ける
                'required'
            ],
        ];

        return $rule;
    }
}

ちなみにtrueを返却しているauthorizeメソッドではバリデーション前処理(例えば認証)が実装可能
前処理が必要無ければauthorizeメソッド自体を削除してもtrueに書き換えた場合と同じ結果になる

複数formでバリデーションを分けたい場合
type=sbmitにnameを指定して、valueの値でif分岐させる

rulesメソッド記載例
public function rules(): array
{
    $rule =[];
    $request = $this->all();
    $submit = isset($request['submit_name']) ? $request['submit_name'] : 'デフォルト';

    if ($submit == '検索') {
        // 検索フォームでのルールを記載
    } else {
        // 検索以外でのルールを記載
    }
    return $rule;
}

よく使ってる気がするルール一覧

詳細は公式ドキュメントの「使用可能なバリデーションルール」で確認
メッセージはデフォルトが英語なので、日本語化した際に任意で変更する:muscle:

◆ 必須

'required'

メッセージ例:
'required' => ':attributeは必ず指定してください。'

◆ 正規表現

'nullable', // 必須入力以外の場合、空文字時にエラーを回避できる
'regex:/\A[0-9]{4}\z/' // スラッシュ間に任意のルールを記載する

メッセージ例:
'regex' => ':attributeに正しい形式を指定してください。'

正規表現でよく見る^と$では、PHPの場合不具合が出るのでAとzで記載しています

◆ 他の要素に特定の入力があるとき必須にする

'required_if:name,value'

メッセージ例:
'required_if' => ':otherが:valueの場合、:attributeも指定してください。'

◆ inputの内容を指定する場合

ラジオボタンやチェックボックス、セレクトボックスといった入力値に制限を設ける場合
別の値が送信されないようチェックする際に利用する
例えば以下のルールを記載した場合、config > test.phpファイルのvariable_name内で指定していないキーを送信するとエラーになる

'Rule::in(config('test.variable_name'))'
指定する値のconfigファイル記載例
// ファイルの場所:config>test.php
<?php
    return [
        'variable_name' => [
            '1' => 'お問い合わせ',
            '2' => 'その他',
        ],

    ];

メッセージ例:
'in' => '選択された:attributeは正しくありません。'

◆メールアドレス

'email:strict,dns,spoof'

メッセージ例:
'email' => 'メールアドレスの入力形式に誤りがあります。'

emailのみ指定した場合、存在しないドメインやなりすましメールアドレスが通ってしまうため、必要に応じてstrictやdnsといったバリデーションスタイルを適応する

バリデーションスタイルは以下6種類
コードを見る限りfilterfilter_unicode以外のバリデーションスタイルはEmailValidatorライブラリを利用している模様
チェック内容?はドキュメントに詳細が無くいため、ざっくりで書いてます
間違っていたらすいません
※デフォルトではrfc: RFCValidationが適応されている

バリデーションスタイル チェック内容?
rfc: RFCValidation RFC(5321,5322,6530,6531,6532,1035)に準拠しているか
strict: NoRFCWarningsValidation rfcの厳格バージョン、RFCエラーだけではなく警告も含める
dns: DNSCheckValidation DNSにメールアドレスのドメインが存在するか
spoof: SpoofCheckValidation なりすましメールでないか
filter: FilterEmailValidation PHPの関数filter_var()によるチェック
filter_unicode: FilterEmailValidation::unicode() PHPの関数filter_var()によるチェック ※ Unicode 文字を許可

◆パスワード

Password::min(X) // 最低X文字以上
         ->letters() // 最低1文字の入力必須
         ->mixedCase() // 大文字小文字が1文字ずつ必要
         ->numbers() // 1文字以上の数字入力が必要
         ->symbols() // 1文字以上の記号が必要
         ->uncompromised() // 漏洩パスワードでないかチェックする

メッセージ例:

'password' => [
    'letters' => ':attributeは1文字以上入力してください。',
    'mixed' => ':attributeには大文字と小文字をそれぞれ1文字以上含めてください。',
    'numbers' => ':attributeには数字を1文字以上含めてください。',
    'symbols' => ':attributeには記号を1文字以上含めてください。',
    'uncompromised' => '別の:attributeを入力してください。',
]

uncompromised()は個人情報が漏洩していないかを照会できるウェブサイトHave I Been Pwned?に掲載されたメールアドレス&パスワードであるかを確認しているらしい
ちなみに引数に数値を入力すると、チェック時エラーにする閾値を上げることが出来る

また、デフォルトルールの設定も可能
(複数ページで同じパスワードルールを利用したい場合に便利)

Password::defaults()

設定は以下例のようにサービスプロバイダのbootメソッドに記載する

Providers/AppServiceProvider.php
use Illuminate\Validation\Rules\Password;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Password::default(function () {
            return Password::min(8)->mixedCase()->numbers()->symbols()->uncompromised();
        });
    }
}

◆入力一致

確認用メールアドレス入力といった、別のエリアの入力値と比較したい場合に便利

'same:other' // otherは一致にしたい入力エリアのname値

メッセージ例:
'same' => ':attributeが:otherと一致していません。'

エラーメッセージ日本語化

① langファイルを用意する

デフォルトではlangディレクトリが無いので、まずは以下コマンドでインストールする

ターミナルで以下実行
php artisan lang:publish

② langファイル直下のenフォルダをコピーし、名前をjaに変更する

③ configの言語設定を書き換える

config/app.php
'locale' => 'ja',
'fallback_locale' => 'ja',

④ jaファイルを利用するように.envファイルのLOCALEを書き換える

.env
APP_LOCALE=ja

⑤ validation.phpファイルの英文を日本語に書き換える

利用する予定のバリデーションエラーメッセージのみ書き換えればokです

lang/ja/validation.php
return [
    'required' => ':attributeを入力してください',
    'attributes' => [ // :attributeに入るnameに紐づく文字列を指定する
        'name' => '名前',
        'name.*' => ':position番目の名前', // 同じnameが複数あり、何番目かを指定したい場合
    ]
];

対応する日本語は以下URLに一覧があったのですが、ページが404になってしまった...悲しい...:cry:
https://readouble.com/laravel/8.x/ja/validation-php.html

Controllerクラスの設定

① バリデーションルール参照のため、requestクラスを読み込む

フォームのリクエストを受け取るコントロールクラスに記載
use App\Http\Requests\クラス名;

② 対象メソッドの引数$requestの型に作成したクラス名を指定する

public function メソッド名 (requestのクラス名 $request){
    // controllerでrequestの内容からエラーメッセージを返却したい場合の記載例
    // withErrorsの引数は配列で複数メッセージを送信可能
    if (!isset($request['name'])) {
        return back()->withErrors(['request_error' => 'エラーメッセージ'])->withInput();
    }
}

設定後post時にバリデーションチェックでエラーが発生した際に
自動でget画面へリダイレクトされる

Viewでエラーメッセージを表示

・全部まとめて表示したい場合

bladeファイル
@if($errors->any())
    @foreach ($errors->all() as $error)
        {{ $error }}
    @endforeach
@endif

・指定して表示したい場合

bladeファイル
@error('name')
    {{ $message }}
@enderror

おまけ

:paperclip: 自動リダイレクトを止める

バリデーションエラー時の自動リダイレクトに割り込みたいそんな時のため(?)のメモです

requestクラス記載例
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class requestクラス名 extends FormRequest
{
    // バリデーションエラー時のリダイレクト処理をごり押しオーバーライド
    protected function failedValidation(Validator $validator){}

    // controllerでバリデーションデータ取得用の処理
    public function getValidator()
    {
        return $this->validator;
    }
}

返却されるValidatorオブジェクトについては以下サイトを参照していたんですが、
Laravel12リリース後あたりから404になってしまった...悲しい...:cry:
https://laravel.com/api/10.x/Illuminate/Validation/Validator.html
※例えばエラー有無判定はfails()、inputデータが欲しい場合はgetData()

controllerクラス記載例
public function メソッド名(requestクラス名 $request) {
    // バリデーションデータ取得
    $error_message = $request->getValidator();

    // バリデーションAfterフック処理
    $error_message->after(function($error_message) {
    $get_data = $error_message->getData();
        // 実行したいチェックを記載
        if (!isset($get_data['name'])) {
            // エラーを返却
            $error_message->errors()->merge(['name' => ['message']]);
        }
    });
}

afterについては以下公式ドキュメントの「追加バリデーションの実行」を参照
https://readouble.com/laravel/10.x/ja/validation.html

あとがき

ここまで閲覧してくれて感謝です!!
最初にまとめていた時期がLaravel10の段階だったので、ドキュメント関連は10のリンク置いている箇所があります:bow:

今後、新しいバージョンで書いた際に気づきがあれば追記するかもしれない...
なおリダイレクト割り込みは特殊枠だと思うんで多分あんま使わない...多分...

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?