LoginSignup
1
0

More than 3 years have passed since last update.

FormRequestで自作のファイル拡張子バリデーションを作ってみた

Posted at

環境

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のみにします)

app/Http/Requests/CreateItemRequest.php
<?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クラスを渡すだけです。

ItemController.php

//中略

use App\Http\Requests\CreateItemRequest;

//中略

public function store(CreateItemRequest $request)
{
    //
}

自作で拡張子バリデーションを作成する

下記にバリデーションを書いていきます。withValidatorメソッドは、rules()で指定したバリデーション評価前に実行されるようです。

app/Http/Requests/CreateItemRequest.php

public function withValidator($validator)
{
    //ここにバリデーションを書いていきます
}

app/Http/Requests/CreateItemRequest.php
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('', 'アップロードされたファイルは画像ファイルではありません。');
        }
    });
}

拡張子は、大文字でも小文字でもチェックできるよう、一度拡張子を小文字に変換します。エラー時のメッセージは直接書きます。

最終的なファイル

app/Http/Requests/CreateItemRequest.php
<?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

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