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からの対応です。
メルマガ購読の申し込みはこちらから。
[…] コントローラのコンストラクタに書けばいいかと思い調べてみたら、Laravel5.3以降は普通に書いても動かなくなったということで(参考ページ)回避策として下のような書き方が使えるということがわかりました。 […]