38
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Laravel] バリデーションデータに前処理したい

Posted at

[Laravel] バリデーションデータに前処理したい

当てはまるケース

  • フォーム入力データとデータベース保存データの形式が違う.例えば…
    • 全角・半角変換
    • 先頭・末尾の空白を取り除く
    • ユーザーには090で始まる形式の携帯電話番号を入力してもらっているが,システム的には E164 で扱いたい

バリデーターに流すデータに前処理を施すことで,unique チェックも前処理後のデータでできるようになります.

Laravel にはデフォルトで文字列をトリミングするミドルウェアが含まれているので,前処理にトリミングを行う必要はありません.

Form Request を使う場合

FormRequest クラス内部において,

Illuminate\Foundation\Http\FormRequest.php:81
<?php

    /**
     * Create the default validator instance.
     *
     * @param  \Illuminate\Contracts\Validation\Factory  $factory
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function createDefaultValidator(ValidationFactory $factory)
    {
        return $factory->make(
            $this->validationData(), $this->container->call([$this, 'rules']),
            $this->messages(), $this->attributes()
        );
    }

    /**
     * Get data to be validated from the request.
     *
     * @return array
     */
    protected function validationData()
    {
        return $this->all();
    }

のように,validationData() メソッドでバリデーション用データを取得し,バリデーターに流しています.

デフォルトでは all() メソッドでフォームの全項目を配列で返しているので,validationData() メソッドを上書きし,この配列に前処理すれば良いことがわかります.

CreateUserRequest.php
<?php

class CreateUserRequest extends FormRequest
{
    /**
     * Get data to be validated from the request.
     *
     * @return array
     */
    protected function validationData()
    {
        $data = $this->all();
        // 前処理:例えば全角英数字を半角に変換する
        if (isset($data['name']))
            $data['name'] = mb_convert_kana($data['name'], 'a');
        return $data;
    }
    
}

FormRequest を使わない場合

Validator ファサードを使うのが無難でしょう.

Laravel 本家の例をもとに書いてみます.

PostController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * Store a new blog post.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $data = $request->all();
        // ここで前処理
        if (isset($data['name']))
            $data['name'] = mb_convert_kana($data['name'], 'a');
      
        $validator = Validator::make($data, [
            'name' => 'required|string|unique:users',
        ]);
        $validator->validate();
      
        // バリデーション通過後の処理…
    }
}

注意:バリデーション後のデータ

前処理はバリデーション用のデータにのみ適用されるので,通過後の $request に含まれる入力データは前処理がかかっていません.

データを利用する際にはもう一度前処理を実行する必要があります.

参考

38
35
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
38
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?