Laravelのバージョン5.3がリリースされてから、かれこれ1ヶ月。使い始めてみました。

以前のバージョンからバージョン5.*への変更に比べれば、そう注意しなければならない変更はないのだけれど、とっても注意することありました。

Laravel5.2では、コントローラのコンストラクタでこんなこと可能でした。


namespace App\Http\Controllers;

use Illuminate\Http\Request;

use Auth;

class HomeController extends Controller
{
    protected $options;

    public function __construct()
    {
        $user = Auth::user();

        $this->options = $user->options; //ログインしたユーザーの設定オプションを取得
    }
}

認証されたユーザー、つまりログインしたユーザーの認証の情報にアクセスすることが、コントローラのコンストラクタで可能でした。

同じコントローラの他のメソッドで何回も同じことを行うのは面倒なわけで、また以下のようにすでにroutes.php(5.3では、app/routes/web.phpとなります)の設定で、パスワード保護されているので、認証されたユーザーの情報を共有できる理想の場所というわけです。

Route::get('login', 'Auth\AuthController@showLoginForm');
Route::post('login', 'Auth\AuthController@login');
Route::get('logout', 'Auth\AuthController@logout');

Route::group(['middleware' => 'auth'], function() {
	Route::get('home', 'HomeController@index');
});

しかし、それは「してはいけないこと」だったのです!Laravel5.3になるやいなや、認証したユーザーのAuth::userがnullを返すようになりました。

そして、Laravelの作者(Mr. Tayler)の思惑とは逆に、こんなことをやっている開発者はごまんといたわけです。

以下のやり取りをみていると、

突如の変更に困ったユーザーとそれに対応する作者たちの会話

作者は、ユーザー認証はクッキーやセッションがあってこそ成り立つものであり、それが入ってくるのはコントローラのメソッドにおいてのrequestの引数である。それゆえにrequestがないコンストラクタでその情報を取得するのはデザイン上「悪い」と。

しかし、コンストラクタはいろいろと共有できる便利な場所であり、しかも今までそこで問題なかったのだからね。

作者もそれを理解して、すぐに以下のような対応をしてくれました。


    public function __construct()
    {
        $this->middleware(function ($request, $next) {
            $this->options = Auth::user()->options;//ログインしたユーザーの設定オプションを取得

            return $next($request);
        });
    }

Laravel 5.3.4からの対応です。

By khino

One thought on “Laravel 5.3 コントローラのコンストラクタの重要な変更”

Comments are closed.