フォームリクエスト
以下のようにフォームリクエストを作成し、コントローラーから処理を分離できる。
php artisan make:request HogeRequest
- StoreXXXXRequestとすることが多いっぽい
App\Http\Request\HogeRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreContactRequest extends FormRequest
{
public function authorize()
{
return false;
}
public function rules()
{
return [
//
];
}
}
- 簡単に認可・バリデーションを行うことが可能
- コントローラーからバリデーションを切り離せる
- テストしやすい
- Fat Controllerを避けられる
authrize()
- バリデーションを受ける前に実行されるもの
- falseの場合は
403 Forbiddenを返し、アクセスを拒否する - 初期状態はfalseなのでtrueに書き換える
public function authorize()
{
return true;
}
許可の例
- ロールがadminのユーザーのみ許可することもできる
public function authorize()
{
return auth()->user()->role === 'admin';
}
- カスタム権限システムやパーミッションベースのシステムを使用して、ユーザーに特定の許可がある場合のみリクエストを許可もできる
以下は編集権限を持っているユーザーのみ許可している
public function authorize()
{
return auth()->user()->hasPermission('edit-posts');
}
- 自分のプロフィールを編集する際など、特定のリソースの所有者だけがリクエストを許可
public function authorize()
{
$profile = Profile::find($this->route('profile_id'));
return auth()->user()->id === $profile->user_id;
}
- このほかにも時間やIPアドレス、年齢などに基づいて許可するなどができる
バリデーション
バリデーションの基礎
- バリデーションロジック
- Illuminate\Http\Requestオブジェクトが提供するvalidateメソッドを使用
public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
// key => value(条件)
]);
// 配列のような書き方もできる
$validatedData = $request->validate([
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
]);
return redirect('/posts');
}
- ビューでエラーを表示する
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
フォームリクエストバリデーション
- フォームリクエストのrulesにバリデーションを書く
php:App\Http\Request\HogeRequest.php
public function rules(): array
{
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
}
使用可能なバリデーションルール
- 必須かどうか、日付やメールアドレスかどうかなどさまざまなバリデーションが用意されている
- よく使うもの
- required:必須
- string:文字列であるか
- max:20:最大長
- email:メールアドレスか
- nullable:nullであることを許容する
- boolean:true、false、1、0、"1"、"0"のいずれかか
- accepted:利用規約などに使う。"yes"、"on"、1、"1"、true、"true"かどうか
コントローラーのstoreでバリデーションを使用する
App/Http/Controllers/HogeController.php
use App\Http\Requests\HogeRequest;
// public function store(Request $request)
// ↓↓↓↓
public function store(HogeRequest $request)
{
}
- おさらい:storeはフォームで送られてきた内容を、データベースに新規保存している
ビューでエラーを表示する
- パーツを作って呼び出すのがよい
/resources/views/components/input-error.blade.php
@props(['messages'])
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
// 一箇所に全てのエラーを表示
<x-input-error :messages="$errors->all()" />
// どのエラーを出すか選ぶこともできる
<x-input-error :messages="$errors->get('email')" />
その他参考
バリデーションの方法3つ
- Illuminate\Http\Requestのvalidateメソッド
- Validatorファサード
- FormRequest(フォームリクエスト)
よく使うバリデーションや書き方の例
- よく使うバリデーションルール
- 独自でバリデーションルールを作れる
- エラーメッセージのカスタマイズ
- 多言語
- カスタムメッセージ
- エラーメッセージの動的な切り替え
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($request->all(), [
'age' => 'required|integer|min:18',
], [
'age.min' => function ($message, $attribute, $rule, $parameters) {
$minimumAge = $parameters[0];
return "申し訳ありませんが、{$minimumAge}歳未満の方は登録できません。";
}
]);
public function messages()
{
$messages = [
'title.required' => ':attributeは必須です。',
'content.min' => ':attributeは最低:min文字必要です。',
];
// ユーザーの役割に基づいてメッセージを変更
if (auth()->user()->isAdmin()) {
$messages['title.required'] = '管理者は必ずタイトルを入力してください。';
}
return $messages;
}
など
- テスト可能なバリデーションや、ファイルアップロード時のバリデーションの書き方なども記載されている