読者です 読者をやめる 読者になる 読者になる

localdisk

PHP とか Java とか Web とか好きなことを書きます。

Laravel 5 はこう変わる! メソッドインジェクションとFormRequest編

注意!

このエントリは 2014/09/30 時点の情報です。これからどんどん変わっていく可能性があるので鵜呑みはダメ、絶対。

はじめに

11月にリリースされる Laravel5 の変更点を説明していきます。前回は

Laravel4 では存在しなかった FormRequestメソッドインジェクションについて説明します。個人的には一番の目玉です。

メソッドインジェクション

Laravel4 にもあった Ioc コンテナは今までコンスタラクタインジェクションしかできませんでした。

<?php

class HomeController extends Controller 
{
    /**
     * User 
     * 
     * @var \App\User
     */
    private $user;

    /**
      * コンストラクタインジェクション
      */
    public function __construct(User $user)
    {
        $this->user = $user;
    }
}

Laravel5 ではメソッドインジェクションが可能になったのでこうかけるようになりました。

<?php

class HomeController extends Controller 
{
    public function index(User $user)
    {
        // インジェクションされてる!
        dd($user);
    }

これは嬉しい変更ですね。助かります。

FormRequest

さて、メソッドインジェクションを踏まえて FormRequest の説明をします。FormRequest は既存の Request クラス(Laravel4 でいうところの Input + Request クラス)にValidationと認証機能(?)を足したものです。

まずは作ってみましょう。

php artisan make:request App\\Http\\Requests\\HomeRequest

ポイントは名前空間\\ で区切ってやるのがポイントです。ここらへん以前は(3日前くらい)は名前空間を付ける必要がなかったのですが、現時点では必要です。もしかしたらいらなくなるかもしれません(Laracasts を収録した段階では必要なかった模様)。すると app/Http/Requests にこんな感じのファイルが出来上がります。

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class HomeRequest extends FormRequest
{

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
                //
        ];
    }

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return false;
    }

}

rules メソッドauthorize が実装されています。rules は Validaiton ルールを書く場所です。

<?php
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name'     => 'required',
            'email'    => 'required|email',
            'password' => 'required|min:8',
        ];
    }

こんな感じに書いて…コントローラーにインジェクションすると、Validation が自動に実行されます。Validation がうまく行かなかった時はデフォルトで前画面に戻ります。挙動を変えたい場合は FormRequestredirect フィールドを定義してください。細かい挙動は Illuminate\Foundation\Http\FormRequest#getRedirectUrl を参照してください

<?php
    public function store(HomeRequest $request)
    {
        dd($request->all());
    }

今までは Controller に書いたり Ardent のように Eloquentメソッドをオーバーライドして Model 側で Validation を実行させたりしていましたが、この変更で決着をみたんじゃないかと思います。

Validaitonの必要がない場合は \Illuminate\Http\Request をインジェクションするのもありですね。

<?php
    public function store(Illuminate\Http\Request $request)
    {
        dd($request->all());
    }

でも、これルートパラメータと相性悪いかもしれませんね。調査しきれていないので解決方法があるかもしれませんが。


で次の、authorize メソッドなんですが、これイマイチどう使えばいいかわかってません。 認証されたかどうかのチェックなら AuthFilter 使えばいいしなぁ…。一応説明するとこのメソッドfalse を返すと 403 が返却されます。 true を返すと次の処理へ進みます。forbiddenResponse をオーバーライドすることで挙動を変えることができます。

終わりに

ちょっと長めになりましたが、Validation の手間が大幅に軽減されたのは嬉しい限りです。リリースが楽しみですね。
次回は新たに追加された ServiceProvider の話か、route:cache の話をしたいと思います。