LaravelにはHTTP例外を投げるヘルパ関数abortが用意されています。
abort
関数は、例外ハンドラによりレンダーされるであろう、HTTP例外を投げます。abort(403);
例外のレスポンステキストと、カスタムヘッダを指定することもできます。
abort(403, 'Unauthorized.', $headers);
abort(403);と一言記述するのみで権限エラーである403のエラーページにクライアントを飛ばせます。この使い方が最も主で伝統的な使い方です。しかしもう少し複雑なHTTPレスポンスを返したい場合もあります。
使い方が書かれている公式の翻訳ドキュメントにおいて、abort関数はステータスコードとメッセージとヘッダを指定するだけの簡易な関数に見えますが、実際はもっと自由です。ヘルパ関数abortは/vendor/laravel/framework/src/Illuminate/Foundation/helpers.phpにあるabort関数を呼び出しています。その呼び出される部分が次です。
// Laravel5.7版のコード if (! function_exists('abort')) { /** * Throw an HttpException with the given data. * * @param \Symfony\Component\HttpFoundation\Response|\Illuminate\Contracts\Support\Responsable|int $code * @param string $message * @param array $headers * @return void * * @throws \Symfony\Component\HttpKernel\Exception\HttpException * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException */ function abort($code, $message = '', array $headers = []) { if ($code instanceof Response) { throw new HttpResponseException($code); } elseif ($code instanceof Responsable) { throw new HttpResponseException($code->toResponse(request())); } app()->abort($code, $message, $headers); } }
注目する部分はPHPDocの$codeで指定されている型と関数が始まった直後のif文部分です。これは$codeにはステータスコードになるintのみでなく\Symfony\Component\HttpFoundation\Responseを継承するか\Illuminate\Contracts\Support\Responsableを実装したクラスのインスタンスを引数にすれば、HTTPレスポンスとして適した形で例外の結果をクライアントに返します。
PHPのinstanceofは完全にイコールのインスタンスのみでなく継承元、実装元の場合でも真になります。
PHP: 型演算子 – Manual
このinstanceofの性質からabort関数は例えばこのように使えます。
abort(resnponse()->json("I'm a teapot", 418));
ExceptionクラスやHandlerクラスを気にすることなく例外の結果をJSON型のHTTPレスポンスとしてクライアントに投げられます。
LaravelにはインタフェースIlluminate\Contracts\Support\Jsonableがあり、これを実装したクラスはJSON化が担保され、至る所でJSONとして扱えます。JsonableはModelやCollectionを始めとして多くのもので実装されています。このため次の様なこともできます。
// User.php class User extends Model implements Responsable { public function isOne() { return $this->getKey() === 1; } public function toResponse($request) { return response()->json($this); } } // 適当な別ファイル $a = User::inRandomOrder(); $a->isOne() ?: abort($a);
Modelの場合、プロパティがJSON化されます。abortに渡されたUserインスタンスのtoResponseメソッドが動作し、response()->json($this)によりJSON化されたUserインスタンスがHTTPレスポンスとして返されます。
この変更はLaravel5.6時に追加されました。
allow giving a response to abort · laravel/framework@4e29889