【Laravel】Laravelでバリデーションを実装する方法

#フォームに実装

## 1) ValidateRequests　トレイトを用いる方法

ValidateRequestsとはControllerクラスに組み込まれたトレイト

```php
class HelloController extends Controller
{
   public function post(Request $request)
   {
       $validate_rule = [
           'name' => 'required',
           'mail' => 'email',
           'age' => 'numeric|between:0,150',
       ];
       $this->validate($request, $validate_rule);
       return view('hello.index', ['msg'=>'正しく入力されました！']);
   }

}
```
validateメソッドが、各フォームの値を指定の制限でチェックし、問題がなければ次の処理を、問題があったら例外が発生し、フォームページが生成されてクライアントに返信される。

また、発生したエラーは **$errors** という変数に格納される。

例えば名前入力欄に、名前入力で発生したエラーを表示する場合は

```php
@if ($errors->has('name'))
  {{$errors->first('name')}}
@endif
```
**has()メソッド**で、引数にしていしたフォームのエラーの有無をチェック。
**first()**メソッドで、最初のエラーメッセージを取得する。また、firstメソッドの代わりに**get()**メソッドを使用すると、その項目のエラーが配列で格納される。
**all()**は、全てのエラーが格納される。


また、valueに**old**というメソッドを使用すると、前回入力した内容が取り出せる。
例えば、名前の入力フォームに **value="{{old('name')}}"**としておけば、エラーの際、再度表示されたフォームページの入力欄に前回入力した内容が格納される。

より便利な、**@errorディレクティブについて**

```php
@error('name')
  {{$messege}}
@enderror
```
nameフォームでエラーがあった場合、tureとなり、$messageにエラー内容が格納される。

## 2) フォームリクエストを用いる方法
リクエストがコントローラーに渡る前に、Requestクラスを継承した**FormRequest**内部でチェックする。 

```
php artisan make:request HelloRequest<フォームリクエスト名>
```
のコマンドで作成する。
**http/Requests/**　に作成される。

```http/Requests/HelloRequest.php
#生成されるソース

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class HelloRequest extends FormRequest
{
   public function authorize()
   {
       return false;
   }

   public function rules()
   {
       return [
           //
       ];
   }
}
```

authrize:
フォームリクエストの利用が許可されているか否かを示す。

rules:
バリデーションションのルールを設定する。

```php
#使用例
class HelloRequest extends FormRequest
{
   public function authorize()
   {
       if ($this->path() ==  'hello')
       {
           return true;
       } else {
           return false;
       }
   }

   public function rules()
   {
       return [
           'name' => 'required',
           'mail' => 'email',
           'age' => 'numeric|between:0,150',
       ];
   }
}
```
pathメソッドでアクセスしたパスをチェック。
rulesメソッドでルールを返す。

```php
#コントローラー
use App\Http\Requests\HelloRequest;　を追加

public function post(HelloRequest $request)
{
   return view('hello.index', ['msg'=>'正しく入力されました！']);
}
```
引数で渡されるクラスが、Requestクラスから、Requestクラスを継承しているFormRequestクラスから、さらに継承しているHelloRequestクラスになっている。

日本語化

```php
class HelloRequest extends FormRequest
{
   public function authorize()
   {
       if ($this->path() ==  'hello')
       {
           return true;
       } else {
           return false;
       }
   }

   public function rules()
   {
       return [
           'name' => 'required',
           'mail' => 'email',
           'age' => 'numeric|between:0,150',
       ];
   }

  # messageメソッドをオーバーライドする。
  public function messages()
  {
   return [
       'name.required' => '名前は必ず入力して下さい。',
       'mail.email'  => 'メールアドレスが必要です。',
       'age.numeric' => '年齢を整数で記入下さい。',
       'age.between' => '年齢は０～150の間で入力下さい。',
   ];
  }
}
```
## 3) Validatorを使う
コントローラーのvalidateメソッドを呼び出さず、Validatorクラスのインスタンスを作成して処理をすることで、バリデーションの処理をカスタマイズすることができる。

```php
use Validator;

public function post(Request $request)
{
   $validator = Validator::make($request->all(), [
       'name' => 'required',
       'mail' => 'email',
       'age' => 'numeric|between:0,150',
   ]);

   if ($validator->fails()) {
       return redirect('/hello')->withErrors($validator)->withInput();
   }

   return view('hello.index', ['msg'=>'正しく入力されました！']);
}
```
validatorクラスのmakeメソッド：

validator::make(値の配列, ルールの配列);

validatorクラスのfails()メソッド：
チェックに失敗したらtrueを返す。

withErrorsメソッド：
Validatorで発生したエラーメッセージをリダイレクト先まで引き継ぐことができる。

withInputメソッド:
送信されたフォームの値をそのまま引き継ぐ。

###クエリ文字列に実装
```php

public function index(Request $request)
{
   $validator = Validator::make($request->query(), [
       'id' => 'required',
       'pass' => 'required',
   ]);
   if ($validator->fails()) {
       $msg = 'クエリーに問題があります。';
   } else {
       $msg = '受け付けました。';
   }
   return view('hello.index');
}
```

queryメソッド：
送信されたクエリ文字列を配列の形で返す。
ex)
/index?id=taro&pass=yamada の場合

['id' => 'taro', 'pass' => 'yamada]

あとは同じように、ルール配列を作成してチェックする。

###Validatorを用いて、メッセージをカスタムする。

```javascript
//第３引数にメッセージの配列を入れることによってカスタマイズできる。
Validator::make(値の配列, ルールの配列, メッセージの配列);
```

```javascript
public function post(Request $request)
{
   $rules = [
       'name' => 'required',
       'mail' => 'email',
       'age' => 'numeric|between:0,100',
   ];
   $messages = [
       'name.required' => '名前は必ず入力して下さい。',
       'mail.email'  => 'メールアドレスは必ず入力して下さい。',
       'age.numeric' => '年齢を整数で記入下さい。',
       'age.between' => '年齢は０～100の間で入力下さい。',
   ];
   $validator = Validator::make($request->all(), $rules, $messages);
   if ($validator->fails()) {
       return redirect('/hello')->withErrors($validator)->withInput();
   }
   return view('hello.index');
}
```
###条件に応じてルールを追加する
sometimesメソッド

```javascript
$validater->sometimes(項目名, ルール, function($input){
　処理、、、
 return 真偽値；
});
```
＄inputには、入力された値がまとめられている。例えば$input->nameで取得可能。
この数値を処理でチェックし、結果falseがreturnされたら、

項目名：ルール　のバリデーションが追加される。

例）

```etc.js
  $validator->sometimes('age', 'max:200', function($input){
    return !is_int($input->age);
   });
```
ageが整数の場合、falseが返され
'age'=>'max:200'のルールが追加される。