Laravelのコントローラにおいて、abort(404)
のヘルパーをコールすることで簡単に予期しないアクセスを、Not Foundのエラーページの表示ができます。しかし、Not Foundページの代わりにリダイレクトして違うページに飛ばしたいときには、redirect()
のヘルパーをabort()
同様に好きな場所で使うことはできません。
そう書いても何を言っているかわからないと思いますので、まず、商品(Product)の情報を閲覧するコントローラを使って、abort()
とredirect()
の紹介から。
abort()
は以下のように単独でコードに配置します。
namespace App\Http\Controllers; use App\Product; use App\Http\Controllers\Controller; class ProductController extends Controller { public function show(Product $product) { if ($product->active_flag == 'N') { // 無効な商品なら、 abort(404); // Not Foundページを表示 } return view('user.product.show')->with(compact('product')); // 商品のページを表示 } }
しかし、redirect()
は、以下のようにreturnが必要です。
... class ProductController extends Controller { public function show(Product $product) { if ($product->active_flag == 'N') { // 無効な商品なら、 return redirect('home'); // ホームページにリダイレクト } return view('user.product.show')->with(compact('product')); // 商品のページを表示 } }
この違いは、abort()
がHttp Exceptionをthrowするのに対して、redirect()
は、\Illuminate\Http\RedirectResponseのオブジェクトを返すからです。
さて、上のコントローラを変更して、以下のように条件文を新規のメソッドに移します。現在の条件は簡単だけれど将来はたいそう複雑になるぞ、という仮定です。
... class ProductController extends Controller { public function show(Product $product) { $this->checkProduct($product); // 条件文が複雑になるので新規の関数を作成 return view('user.product.show')->with(compact('product')); // 商品のページを表示 } private function checkProduct($product) { if ($product->active_flag == 'N') { // 無効な商品なら、 return redirect('home'); // ホームページにリダイレクト } } }
一見たわいもない変更ですが、これを実行すると、なんと無効である商品の表示ページが表示されます。ホームページにリダイレクトはされません。問題は、checkProduct()
がRedirectResponseを返すのに、コールした側でreturnが使用されていないからなのですね。
しかし、
... class ProductController extends Controller { public function show(Product $product) { return $this->checkProduct($product); return view('user.product.show')->with(compact('product')); // 商品のページを表示 ...
こうすると、商品が有効なときもそこでリターンするために商品のページが表示されずに問題です。さてさて、どうしたらよいでしょう?
ということで、あれこれ調べていたら、abort()
を使用してリダイレクトが可能なことがわかりました。以下のように、abort()
の引数に404のようなHttpステータスのコードの代わりにredirect()
を渡すことが可能なのです。以下が変更後のコードです。素晴らしい!
... class ProductController extends Controller { public function show(Product $product) { $this->checkProduct($product); // 条件文が複雑になるので新規の関数を作成 return view('user.product.show')->with(compact('product')); // 商品のページを表示 } private function checkProduct($product) { if ($product->active_flag == 'N') { // 無効な商品なら、 abort(redirect('home')); // ホームページにリダイレクト } } }メルマガ購読の申し込みはこちらから。