abort_unless — 条件が「偽」なら即座にHTTP例外で中断

helper
  • カテゴリ: helper
  • 掲載バージョン: Laravel 12・PHP 8.4
  • 名前空間 / FQCN / コマンド: abort_unless()
  • 関連: abort / abort_if / throw_unless / abort(403, …) / Gate::authorize
  • 変更履歴: (要確認事項なし)

要点(TL;DR)

  • 条件が満たされないとき(false)に、指定ステータスのHTTP例外を投げて処理を止める。
  • abort_unless($isAdmin, 403);
  • よくある罠
    • abort_unless($user, 403) のように「truthy」に頼ると意図せず通る/落ちる(null と空文字など)
    • 例外メッセージは本番で露出しうる(デバッグ用の内部情報を入れない)
    • $codeint だけでなく Response|Responsable も渡せる(挙動を統一しないと読みにくい) (api.laravel.com)

概要

abort_unless() は、条件が true であることを要求し、満たされない場合は HTTP例外(ステータスコード付き) を投げて即座に中断します。認可チェックや前提条件(存在確認・機能フラグ・署名検証など)を「1行」で書きたいときに便利です。 (Laravel)

構文 / シグネチャ

abort_unless(bool $boolean, Response|Responsable|int $code, string $message = '', array $headers = []);
  • 引数
引数必須既定値説明
$booleanboolなしtrue であることを要求する条件(false なら中断)
$codeResponse | Responsable | intなしHTTPステータスコード、または返したいレスポンス
$messagestring''例外メッセージ(エラーページ等で使われうる)
$headersarray[]レスポンスヘッダ(例: ['X-Reason' => '...']
  • 戻り値void(中断しない場合は何も返さず続行) (api.laravel.com)
  • 例外/副作用:条件が false の場合、HTTP例外を投げて後続処理は実行されません。 (Laravel)

使用例

最小例

<?php

use Illuminate\Support\Facades\Auth;

abort_unless(Auth::check(), 401, 'Unauthenticated.');
// ここ以降はログイン済みだけが到達する

実務例

<?php

use App\Models\Project;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;

Route::post('/projects/{project}/deploy', function (Request $request, Project $project) {
    // 認可(できなければ 403 で中断)
    abort_unless(Gate::allows('deploy', $project), 403);

    // 署名ヘッダが必須(なければ 422 で中断)
    abort_unless($request->hasHeader('X-Signature'), 422, 'Missing signature.');

    // …デプロイ処理…
    return response()->json(['ok' => true]);
});

よくある落とし穴・注意

  • 条件は「bool」に寄せる$user / $id をそのまま渡すより、$user !== nullfilled($id) のように意図を固定すると安全です。
  • メッセージに機微情報を入れない:内部ID・設定値・署名検証の詳細などは露出しない設計に。
  • $code を int 以外で混在させないResponse|Responsable を許容できるのは便利ですが、チーム内で方針がないと読みづらくなります。 (api.laravel.com)

代替・関連APIとの比較

  • abort_if($cond, 403):条件が true のとき落とすabort_unless の反対)。読みやすい方を選ぶ。 (Laravel)
  • abort(403, ...):条件分岐を自分で書く前提。複雑な分岐やログ出しが必要ならこちら。
  • throw_unless($cond, SomeException::class):HTTPに限らず例外種別を選びたいとき(ドメイン例外など)。
  • Gate::authorize('ability', $model) / FormRequest::authorize():認可は「仕組み」に寄せたいとき(方針・テスト・メッセージ統一がしやすい)。

テスト例(Pest)

<?php

use Illuminate\Support\Facades\Route;

it('aborts with 403 when condition is false', function () {
    Route::get('/__test_abort_unless', function () {
        abort_unless(false, 403);
        return 'ok';
    });

    $this->get('/__test_abort_unless')->assertForbidden();
});

トラブルシュート(エラー別)

症状/エラー原因対処
期待したのに中断しない条件が truthy になっている(例:"0" は truthy)明示的に === / !== で bool 化する
403 のはずが別のレスポンスになる$code に `ResponseResponsable` を渡している
エラーページにメッセージが出てしまう$message を入れている本番向けメッセージにする/入れない方針にする

参考リンク

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする