Laravel 5.0 バリデーション

基本の使用法

Laravelにはシンプルで便利なValidationクラスが用意されており、データーの正当性確認やエラーメッセージの取得ができます。

基本的なバリデーション例

$validator = Validator::make(
    ['name' => 'Dayle'],
    ['name' => 'required|min:5']
);

makeメソッドに渡す最初の引数はバリデーションを行うデーターです。2つ目の引数はデーターに適用するバリデーションルールです。

ルールの指定に配列を使用

複数のルール指定はパイプ(縦線)で区切るか、配列で分割し指定します。

$validator = Validator::make(
    ['name' => 'Dayle'],
    ['name' => ['required', 'min:5']]
);

複数フィールドのバリデーション

$validator = Validator::make(
    [
        'name' => 'Dayle',
        'password' => 'lamepassword',
        'email' => 'email@example.com'
    ],
    [
        'name' => 'required',
        'password' => 'required|min:8',
        'email' => 'required|email|unique:users'
    ]
);

Validatorインスタンスが生成されたら、fails(もしくはpasses)メソッドを使用し、バリデーションを実行します。

if ($validator->fails())
{
    // 与えられたデーターはバリデーションをパスしなかった
}

バリデーションが失敗すると、バリデーターよりエラーメッセージが取得できます。

$messages = $validator->messages();

メッセージではなく、バリデーションで失敗したことを示す配列へアクセスすることも可能です。使用するにはfailedメソッドを使ってくだい。

$failed = $validator->failed();

ファイルのバリデーション

Validatorクラスはファイルに対し、sizemimesなどのようないくつかのバリデーションルールを提供しています。ファイルをバリデーションする場合は、他のデータと一緒にバリデーターへ渡してください。

バリデーション後のフック

バリデーションには、完了した後に実行するコールバックを追加することもできます。これにより、簡単に他の確認作業を追加したり、メッセージコレクションへエラーメッセージを追加したりさえできます。これを行うには、バリデーションインスタンスに対し、afterメソッドを使用してください。

$validator = Validator::make(...);

$validator->after(function($validator)
{
    if ($this->somethingElseIsInvalid())
    {
        $validator->errors()->add('field', 'Something is wrong with this field!');
    }
});

if ($validator->fails())
{
    //
}

必要に応じて、多くのafterコールバックを追加することもできます。

コントローラーバリデーション

もちろん、バリデーションを行うために、毎回手動でValidatorインスタンスを生成し、確認するのは面倒ですよね。心配ご無用、別の方法もあります!ベースのApp\Http\Controllers\Controllerクラスは、LaravelのValidatesRequestsトレイトを使っています。このトレイトは、送られてくるHTTPリクエストをバリデーションするための便利なメソッドを一つ提供しています。ご覧ください。

/**
 * 投稿されたブログ投稿を保存する
 *
 * @param  Request  $request
 * @return Response
 */
public function store(Request $request)
{
    $this->validate($request, [
        'title' => 'required|unique|max:255',
        'body' => 'required',
    ]);

    //
}

バリデーションが通れば、コードは通常通り実行されます。しかし、バリデーションに失敗すると、Illuminate\Contracts\Validation\ValidationExceptionが投げられます。この例外は自動的に補足され、ユーザーが前にアクセスしたURLへのリダイレクトを生成します。バリデーションエラーも自動的に、セッションへフラッシュデータとして保存されます!

もし、やって来たリクエストがAJAXリクエストであれば、リダイレクトは生成されません。代わりに、バリデーションエラーを表すJSONを含んだ、422ステータスコードのHTTPレスポンスがブラウザへ返されます。

つまり、通常の書き方をした同等のコードはこのようになります。

/**
 * 投稿されたブログ投稿を保存する
 *
 * @param  Request  $request
 * @return Response
 */
public function store(Request $request)
{
    $v = Validator::make($request->all(), [
        'title' => 'required|unique|max:255',
        'body' => 'required',
    ]);

    if ($v->fails())
    {
        return redirect()->back()->withErrors($v->errors());
    }

    //
}

フラッシュデータとして保存されるエラー形式のカスタマイズ

バリデーションが失敗した時に、フラッシュデーターとして保存されるバリデーションエラーの形式をカスタマイズしたければ、ベースコントローラーのformatValidationErrorsをオーバーライドしてください。Illuminate\Validation\Validatorクラスをファイルの先頭でインポートするのを忘れないでください。

/**
 * {@inheritdoc}
 */
protected function formatValidationErrors(Validator $validator)
{
    return $validator->errors()->all();
}

フォームリクエストバリデーション

より複雑なバリデーションのシナリオでは、「フォームリクエスト」を生成したほうが良いでしょう。フォームリクエストは、バリデーションロジックを含んだカスタムリクエストクラスです。フォームリクエストクラスを作成するには、make:request Artisan CLIコマンドを使用します。

php artisan make:request StoreBlogPostRequest

生成されたクラスは、app/Http/Requestディレクトリーへ設置されます。では、バリデーションルールを少しrulesメソッドへ追加してみましょう。

/**
 * リクエストに適用される、バリデーションルールを取得
 *
 * @return array
 */
public function rules()
{
    return [
        'title' => 'required|unique|max:255',
        'body' => 'required',
    ];
}

では、どのようにバリデーションルールを実行するのでしょうか?必要なのは、コントローラーのメソッドで、このリクエストをタイプヒントで指定することです。

/**
 * やってきたブログ投稿を保存する。
 *
 * @param  StoreBlogPostRequest  $request
 * @return Response
 */
public function store(StoreBlogPostRequest $request)
{
    // やってきたリクエストは有効だった…
}

渡されたフォームリクエストは、コントローラーメソッドが呼び出される前に確認されます。既に、バリデーション済みです!

バリデーションに失敗すると、前のアドレスにユーザーを戻すために、リダイレクトレスポンスが生成されます。エラーも表示できるように、フラッシュデーターとしてセッションに保存されます。もし、リクエストがAJAXリクエストであれば、バリデーションエラーを表現するJSONを含んだ、422ステータスコードのHTTPレスポンスがユーザーに返されます。

フォームリクエスト権限

フォームリクエストクラスは、authorizeメソッドも用意しています。このメソッドでは、認証されているユーザーが、指定されたリソースを更新する権限を実際に持っているのかを確認します。例えば、ユーザーがブログポストのコメントを更新しようとしているなら、本人のコメントなのでしょうか?調べてみましょう。

/**
 * ユーザーがこのリクエストの権限を持っているかを判断する
 *
 * @return bool
 */
public function authorize()
{
    $commentId = $this->route('comment');

    return Comment::where('id', $commentId)
                  ->where('user_id', Auth::id())->exists();
}

上の例の中の、routeメソッド呼び出しに注目してください。このメソッドで、例えば{comment}パラメーターのような、呼びだされているルートのURIパラメーター定義にアクセスさせてくれます。

Route::post('comment/{comment}');

authorizeメソッドがfalseを返すと、403ステータスコードのHTTPレスポンスが自動的に返され、コントローラーメソッドは実行されません。

アプリケーションの他の場所で、認証のロジックを行おうと設計しているのでしたら、シンプルにauthorizeメソッドから、trueを返してください。

/**
 * ユーザーがこのリクエストの権限を持っているかを判断する
 *
 * @return bool
 */
public function authorize()
{
    return true;
}

フラッシュデータとして保存されるエラー形式のカスタマイズ

バリデーションが失敗した時に、フラッシュデーターとして保存されるバリデーションエラーの形式をカスタマイズしたければ、ベースコントローラー(App\Http\Requests\Request)のformatErrorsをオーバーライドしてください。Illuminate\Validation\Validatorクラスをファイルの先頭でインポートするのを忘れないでください。

/**
 * {@inheritdoc}
 */
protected function formatErrors(Validator $validator)
{
    return $validator->errors()->all();
}

エラーメッセージの操作

Validatorのインスタンスに対し、messagesメソッドを呼びだせば、エラーメッセージを操作するのに便利な様々なメソッドを持つMessageBagインスタンスが取得できます。

指定フィールドの最初のエラーメッセージ取得

echo $messages->first('email');

指定フィールドの全エラーメッセージ取得

foreach ($messages->get('email') as $message)
{
    //
}

全フィールドの全エラーメッセージ取得

foreach ($messages->all() as $message)
{
    //
}

指定フィールドのメッセージ存在確認

if ($messages->has('email'))
{
    //
}

エラーメッセージのフォーマットを指定し取得

echo $messages->first('email', '<p>:message</p>');

デフォルトでは、エラーメッセージはBootstrapコンパチブルな形式が使われます。

全エラーメッセージをフォーマット指定し取得

foreach ($messages->all('<li>:message</li>') as $message)
{
    //
}

エラーメッセージとビュー

一度バリデーションを実行したら、エラーメッセージをビューで簡単に表示する方法が欲しくなるでしょう。Laravelでは便利に行えます。以下のルートを参考にしてください。

Route::get('register', function()
{
    return View::make('user.register');
});

Route::post('register', function()
{
    $rules = [...];

    $validator = Validator::make(Input::all(), $rules);

    if ($validator->fails())
    {
        return redirect('register')->withErrors($validator);
    }
});

バリデーションに失敗した場合、ValidatorインスタンスをリダイレクトのwithErrorsメソッドに渡していることに注目してください。このメソッドはセッションにエラーメッセージをフラッシュデーターとして保存し、次のリクエストで使用できるようにします。

しかし、GETルートの中で明示的にエラーメッセージをビューに結合していないことにも注目してください。これは常にLaravelがセッションにerrorsが存在しないかチェックしており、存在時は自動的にビューに結びつけてくれるからです。ですから、$errors変数はいつでも全リクエスト中の、全ビューで使用でき、あなたは$errorsはいつでも定義済みだと確信し、安心して使用できるのです。$errors変数はMessageBagインスタンスです。

ですから、リダイレクトした後に、ビューと自動的に結び付けられた$errors変数を便利に利用してください。

<?php echo $errors->first('email'); ?>

名前付きエラーBag

一つのページに複数のフォームがある場合、エラーのMessageBagに名前を付けたいこともあるでしょう。これにより、特定のフォームに対するエラーメッセージを取得できるようになります。withErrorsへの第2引数として、名前を渡すだけです。

return redirect('register')->withErrors($validator, 'login');

これで、$errors変数により、名前付きMessageBagインスタンスへアクセスできます。

<?php echo $errors->login->first('email'); ?>

用意されているバリデーションルール

以下が使用可能なバリデーションルールとその機能のリストです。

accepted

そのフィールドがyeson1trueであることをバリデートします。これは「サービス利用規約」同意のバリデーションに便利です。

active_url

フィルドがPHPの機能であるcheckdnsrrを通して、有効なURLであるかをバリデートします。

after:日付

フィールドの値が与えられた日付以降であるかバリデーションします。日付はPHPのstrtotime関数で処理されます。

alpha

フィールドが全部アルファベット文字であることをバリデートします。

alpha_dash

フィールドが全部アルファベット文字とダッシュ(-)、下線(_)であることをバリデートします。

alpha_num

フィールドが全部アルファベット文字と数字であることをバリデートします。

array

フィールドが配列タイプであることをバリデートします。

before:日付

フィールドが与えられた日付より前であることをバリデートします。日付はPHPのstrtotime関数で処理されます。

between:最小値,最大値

フィールドが指定された最小値最大値の間のサイズであることをバリデートします。sizeルールと同様の判定方法で、文字列、数値、ファイルは評価されます。

boolean

フィールドが論理値として有効であることをバリデートします。受け入れられる入力は、truefalse10"1""0"です。

confirmed

フィールドがそのフィールド名+_confirmationフィールドと同じ値であることをバリデートします。例えば、バリデーションするフィールドがpasswordであれば、同じ値のpassword_confirmationフィールドが入力に存在していなければなりません。

date

パリデーションされる値はPHP関数のstrtotimeを使用し確認されます。

date_format:フォーマット

バリデーションされる値がフォーマット定義と一致するか、PHP関数のdate_parse_from_formatを使用し確認されます。

different:フィールド

フィールドが指定されたフィールドと異なった値を指定されていることをバリデートします。

digits:

フィールドが数値で、の桁数であることをバリデートします。

digits_between:最小値,最大値

フィールドが整数で、桁数が最小値から最大値の間であることをバリデートします。

email

フィールドがメールアドレスとして正しいことをバリデートします。

exists:テーブル,カラム

フィールドの値が、指定されたデータベーステーブルに存在することをバリデートします。

基本的なExistsルールの使用法

'state' => 'exists:states'

カスタムカラム名の指定

'state' => 'exists:states,abbreviation'

さらにクエリーへWHERE節として追加される条件を追加することも可能です。

'email' => 'exists:staff,email,account_id,1'

NULLを"where"節の値として渡せば、データベースの値がNULLであることを追加でチェックできます。

'email' => 'exists:staff,email,deleted_at,NULL'

image

フィールドで指定されたファイルが画像(jpg、png、bmp、gif、svg)であることをバリデートします。

in:foo,bar...

フィールドが指定されたリストの中の値に含まれていることをバリデートします。

integer

フィールドが整数値であることをバリデートします。

ip

フィールドがIPアドレスの形式として正しいことをバリデートします。

max:

フィールドが最大値として指定された以下であることをバリデートします。sizeルールと同様の判定方法で、文字列、数値、ファイルが評価されます。

mimes:foo,bar,...

フィールドで指定されたファイルが拡張子のリストの中のMIMEタイプのどれかと一致することをバリデートします。

mimesルールの基本的な使用法

'photo' => 'mimes:jpeg,bmp,png'

min:

フィールドが最小値として指定された以上であることをバリデートします。sizeルールと同様の判定方法で、文字列、数値、ファイルが評価されます。

not_in:foo,bar,...

フィールドが指定されたリストの中の値に含まれていないことをバリデートします。

numeric

フィールドは数値であることをバリデートします。

regex:正規表現

フィールドが指定された正規表現にマッチすることをバリデートします。

注目: regexパターンを使用する場合は、ルールをパイプ(縦棒)で区切るのではなく、配列で指定することが必要になります。特に正規表現に縦棒を含んでいる場合は該当します。

required

フィールドに入力データーが存在することをバリデートします。

required_with_all:foo,bar,...

The field under validation must be present if the field is equal to any value.

required_with:foo,bar,...

引数で指定されたフィールドのうち、どれかが存在している場合のみ、フィールドが入力されていることをバリデートします。

required_with_all:foo,bar,...

引数で指定されたフィールドのうち、全てが存在している場合のみ、フィールドが入力されていることをバリデートします。

required_without:foo,bar,...

フィールドは、指定された他のフィールドのうちどれかが存在しない場合のみ、この項目が入力されていることをバリデートします。

required_without_all:foo,bar,...

フィールドは、指定された他のフィールド全部が存在しない場合のみ、この項目が入力されていることをバリデートします。

same:フィールド

フィールドが、指定されたフィールドと同じ値であることをバリデートします。

size:

フィールドは指定されたと同じサイズであることをバリデートします。文字列の場合、は文字長です。数値項目の場合、は整数値です。ファイルの場合、はキロバイトのサイズです。

string

フィルードは文字列タイプであることをバリデートします。

timezone

timezone_identifiers_list PHP関数の値に基づき、フィールドがタイムゾーンとして識別されることをバリデートします。

unique:テーブル,カラム,除外ID,IDカラム

フィールドは指定されたデータベースで一意であることをバリデートします。columnオプションが指定されない場合、フィールド名が使用されます。

場合により、バリデーターにより生成されるデータベースクエリーに、カスタム接続を設定する必要があるかもしれません。上記のバリデーションルール、unique:usersではクエリーに対し、デフォルトデータベース接続が使用されます。これをオーバーライドするには、以下のように行います。

$verifier = App::make('validation.presence');

$verifier->setConnection('connectionName');

$validator = Validator::make($input, [
    'name' => 'required',
    'password' => 'required|min:8',
    'email' => 'required|email|unique:users',
]);

$validator->setPresenceVerifier($verifier);

uniqueルールの基本的な使用例

'email' => 'unique:users'

カスタムカラム名の指定

'email' => 'unique:users,email_address'

指定されたIDを無視する

'email' => 'unique:users,email_address,10'

追加のWHERE節を付け加える

さらにクエリーへWHERE節として追加される条件を追加することも可能です。

'email' => 'unique:users,email_address,NULL,id,account_id,1'

上記のルールでは、同一かチェックする対象は、account_id1の行のみになります。

url

フィールドがURLの形式であることをバリデートします。

注目:この機能は、PHPのfilter_varメソッドを使用しています。

条件付きでルールを追加する

ある状況では、そのフィールドが入力配列の中に存在する場合のみ、バリデーションを実行したいことがあると思います。これを簡単に行うには、sometimesルールを追加してください。

$v = Validator::make($data, [
    'email' => 'sometimes|required|email',
]);

上の例では、emailフィールドが、$data配列の中に存在している場合のみ、バリデーションが実行されます。

複雑な条件のバリデーション

時々(sometime)、他のフィールド値が100以上の場合のみ指定したフィールド入力を必須にしたい場合もあるでしょう。もしくは、あるフィールドを指定する場合だけ、2つのフィールドが必要な場合もあるでしょう。この様なバリデーションルールを追加する場合でも、手間はかかりません。最初に固定ルールによりValidatorインスタンスを作成するのは変わりません。

$v = Validator::make($data, [
    'email' => 'required|email',
    'games' => 'required|numeric',
]);

ゲームコレクターのためのWebアプリケーションだと仮定しましょう。ゲームコレクターがアプリケーションに登録する時に、100ゲーム以上所有しているのであれば、なぜそんなに多く持っているのか理由を説明してもらいます。例えば、中古ゲーム店を運営しているのかも知れませんし、ただ収集家なのかも知れません。この条件付きの要求を追加するために、Validatorインスタンスへ、sometimesメソッドを使用してください。

$v->sometimes('reason', 'required|max:500', function($input)
{
    return $input->games >= 100;
});

sometimesメソッドの最初の引数は条件付きでバリデーションを行うフィールドの名前です。2つ目の引数は追加したいルールです。3つ目の引数にクロージャーが渡され、trueをリターンしたら、そのルールは追加されます。このメソッドにより、複雑な条件付きのバリデーションが簡単に作成できます。一度に多くのフィールドに、条件付きバリデーションを追加することもできます。

$v->sometimes(['reason', 'cost'], 'required', function($input)
{
    return $input->games >= 100;
});

注目: クロージャーに渡される$inputパラメーターは、Illuminate\Support\Fluentのインスタンスで、フィールドと入力値にアクセスするためのオブジェクトです。

カスタムエラーメッセージ

必要であれば、デフォルトのエラーメッセージの代わりに、カスタムメッセージを使用できます。指定する方法はいくつかあります。

バリデーターへカスタムメッセージ指定

$messages = [
    'required' => 'The :attribute field is required.',
];

$validator = Validator::make($input, $rules, $messages);

注目: attributeプレースホルダーはバリデーション中のフィールド名に置き換わります。バリデーションメッセージごとに別のプレースホルダーも使用できます。

他のバリデーションプレースホルダー

$messages = [
    'same'    => 'The :attribute and :other must match.',
    'size'    => 'The :attribute must be exactly :size.',
    'between' => 'The :attribute must be between :min - :max.',
    'in'      => 'The :attribute must be one of the following types: :values',
];

指定フィールドにカスタムメッセージ指定

特定のフィールドだけにカスタムメッセージを指定したい場合もあるでしょう。

$messages = [
    'email.required' => 'あなたのメールアドレスを教えてもらう必要があります!',
];

言語ファイルでカスタムメッセージ指定

多くの場合、Validatorに直接カスタムメッセージを渡すよりは、言語ファイルに指定したいでしょう。そのためには、resources/lang/xx/validation.php言語ファイルのcustom配列にメッセージを追加してください。

'custom' => [
    'email' => [
        'required' => 'あなたのメールアドレスを教えてもらう必要があります!',
    ],
],

カスタムバリデーションルール

カスタムバリデーションルールの登録

Laravelは多彩で便利なバリデーションを提供していますが、自分だけの特別なバリデーションを使用したい場合もあるでしょう。カスタムバリデーションルールを登録する一つの方法は、Validator::extendメソッドを使用する方法です。

Validator::extend('foo', function($attribute, $value, $parameters)
{
    return $value == 'foo';
});

カスタムバリデーターのクロージャーは3つの引数を取ります。$attributeはバリデーションをしているフィールド、$valueはその値、$parametersはルールに渡された引数です。

クロージャーの代わりにextendメソッドへクラスとメソッドを渡すこともできます。

Validator::extend('foo', 'FooValidator@validate');

カスタムルールにエラーメッセージも定義する必要があります。同時にエラーメッセージを定義することも、また言語ファイルにエントリーを追加することも可能です。

Validatorクラスの拡張

Validatorにクロージャーのコールバックを追加するより、Validatorクラスそのものを拡張したい場合もあるでしょう。それなら、Illuminate\Validation\Validatorを拡張して自分のValidatorを書くこともできます。そのクラスにvalidateのプレフィックスをつけたバリデーションメソッドを追加してください。

<?php

class CustomValidator extends Illuminate\Validation\Validator {

    public function validateFoo($attribute, $value, $parameters)
    {
        return $value == 'foo';
    }

}

カスタムバリデーターリゾルバーを登録する

次にカスタムバリデーター拡張を登録する必要があります。

Validator::resolver(function($translator, $data, $rules, $messages)
{
    return new CustomValidator($translator, $data, $rules, $messages);
});

カスタムバリデーションルールを作成する場合、エラーメッセージ中で置き換えるカスタムプレースホルダーを定義する必要が起きます。今まで説明したカスタムバリデーションの作成を行い、それからバリデーターにreplaceXXX関数を追加してください。

protected function replaceFoo($message, $attribute, $rule, $parameters)
{
    return str_replace(':foo', $parameters[0], $message);
}

Validatorクラスを拡張せずに、カスタムメッセージへ置き換えたい場合は、Validator::replacerメソッドを使用できます。

Validator::replacer('rule', function($message, $attribute, $rule, $parameters)
{
    //
});

ドキュメント章別ページ

Artisan CLI

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる