浜松のWEBシステム開発・スマートフォンアプリ開発・RTK-GNSS関連の開発はお任せください
株式会社シーポイントラボ
TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:静岡県浜松市中区富塚町1933-1 佐鳴湖パークタウンサウス2F

【Laravel】Laravel5.6以降のヘルパ関数abortは結構自由

 LaravelにはHTTP例外を投げるヘルパ関数abortが用意されています。

abort関数は、例外ハンドラによりレンダーされるであろう、HTTP例外を投げます。

abort(403);

例外のレスポンステキストと、カスタムヘッダを指定することもできます。

abort(403, 'Unauthorized.', $headers);

ヘルパ 5.7 Laravel#method-abort

 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

  • この記事いいね! (1)