環境
Laravel 6.20.8
PHP7.4
はじめに
コントローラーにもバリデーションは書けますが、複雑なバリデーションになればなるほど、コントローラーが肥大化してしまうので、FormRequestクラスを活用します。
FormRequestに自作でバリデーションをどのように書くのか、画像ファイルの拡張子チェックを例にします。
Laravelのバリデーションルールは豊富なので、rulesメソッドにmimesを指定してしまえば、アップロードしようとしているファイルのMIMEタイプはチェックしてくれます。ですが、MIMEタイプも改ざんできてしまうので、同時に拡張子のチェックもしたいと思います。
準備
下記コマンドで、App\Http\Requests配下にFormRequestクラスを生成します。
php artisan make:request CreateItemRequest
すると、下記のようなファイルが作られます。authorize()は、認証関係の判定の処理を書きますが、今回は不要なのでtrueを返すようにします。バリデーションはrules()に書いていき、前述の通りmimesを指定します。(今回はjpgとpngのみにします)
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreateItemRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
'name' => 'required|string|max:255',
'picture_name' => 'required|file|mimes:jpg,png',
}
}
コントローラーの変更点は2点です。作成したFormRequestクラスをuseして、store()などPOST送信を受けるメソッドの引数に、作成したcreateItemクラスを渡すだけです。
//中略
use App\Http\Requests\CreateItemRequest;
//中略
public function store(CreateItemRequest $request)
{
//
}
自作で拡張子バリデーションを作成する
下記にバリデーションを書いていきます。withValidatorメソッドは、rules()で指定したバリデーション評価前に実行されるようです。
public function withValidator($validator)
{
//ここにバリデーションを書いていきます
}
public function withValidator($validator)
{
$validator->after(function ($validator)
{
$file_data = $this->file('picture_name');
$file_extension = $file_data->getClientOriginalExtension(); //拡張子取得
$lower_case_extension = strtolower($file_extension); //拡張子を小文字に変換
if($lower_case_extension !== 'jpg' && $lower_case_extension !== 'png'){
$validator->errors()->add('', 'アップロードされたファイルは画像ファイルではありません。');
}
});
}
拡張子は、大文字でも小文字でもチェックできるよう、一度拡張子を小文字に変換します。エラー時のメッセージは直接書きます。
最終的なファイル
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreateItemRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
'name' => 'required|string|max:255',
'picture_name' => 'required|file|mimes:jpg,png',
}
public function withValidator($validator)
{
$validator->after(function ($validator)
{
$file_data = $this->file('picture_name');
$file_extension = $file_data->getClientOriginalExtension(); //拡張子取得
$lower_case_extension = strtolower($file_extension); //拡張子を小文字に変換
if($lower_case_extension !== 'jpg' && $lower_case_extension !== 'png'){
$validator->errors()->add('', 'アップロードされたファイルは画像ファイルではありません。');
}
});
}
}
おわりに
もともとLaravelが用意してくれているバリデーションルールを使えば、かなりのバリデーションができると思いますが、独自のバリデーションが必要なこともあると思うので、withValidatorメソッドの使い方のメモを残しました。
参考
https://readouble.com/laravel/6.x/ja/validation.html
https://www.ritolab.com/entry/41