最近访客

Laravel 查询构造器中的 when() 方法详解

在日常开发中,我们经常需要根据不同条件动态地拼接 SQL 查询。传统做法一般是用 if 来判断,但这样会打断链式调用,代码显得比较臃肿。Laravel 提供了一个非常优雅的方法 —— when(),让我们能在保持链式调用的同时,灵活地添加条件。


基本语法

$query->when($condition, function ($query, $value) {
    // 当 $condition 为 true 或非空时执行
});

参数说明:

  • $condition:判断条件,如果是 true、非空字符串或非零值,就会进入闭包。

  • $query:当前查询构造器对象。

  • $value$condition 本身,可以直接在闭包中使用。


常见用法

1. 代替 if 判断

传统写法

$query = DB::table('users');

if ($role) {
    $query->where('role', $role);
}
if ($status) {
    $query->where('status', $status);
}

$users = $query->get();

使用 when()

$users = DB::table('users')
    ->when($role, function ($q, $role) {
        $q->where('role', $role);
    })
    ->when($status, function ($q, $status) {
        $q->where('status', $status);
    })
    ->get();

效果完全一样,但链式调用更加优雅。


2. 条件排序

有时候我们需要根据用户选择的字段动态排序:

 
$users = DB::table('users')
    ->when($sortField, function ($q, $sortField) use ($sortDirection) {
        $q->orderBy($sortField, $sortDirection ?? 'asc');
    })
    ->get();


如果 $sortField 为空,就不会执行 orderBy,避免了冗余代码。


3. 复杂条件判断

when() 还支持传入第三个参数,表示 条件不成立时执行的逻辑

$users = DB::table('users')
    ->when($isAdmin, 
        function ($q) {
            $q->where('role', 'admin');
        },
        function ($q) {
            $q->where('role', 'user');
        }
    )
    ->get();

相当于:

 
if ($isAdmin) {
    $query->where('role', 'admin');
} else {
    $query->where('role', 'user');
}



实际项目中的应用

比如处理时间范围过滤:

 
$orders = DB::table('orders')
    ->when($time_min, function ($q, $time_min) {
        $q->where('created_at', '>=', $time_min);
    })
    ->when($time_max, function ($q, $time_max) {
        $q->where('created_at', '<=', $time_max);
    })
    ->get();


如果 $time_min$time_max 为空,对应的条件就会自动忽略,避免手动 if


总结

  • when() 是 Laravel 查询构造器的一个小技巧,能让代码更简洁优雅。

  • 它本质上是 if 判断的链式调用版本。

  • 常见应用场景:条件查询、动态排序、状态过滤、时间范围筛选等。

如果你平时在写复杂查询时还在满屏 if 判断,可以尝试用 when(),你会发现代码清爽了很多。

温馨提示: 本文最后更新于2025-09-13 12:22:21,若文章内容或图片失效,请留言或联系站长反馈!
本站资源均仅供学习和研究使用,请在下载后24小时内删除!
© 版权声明
THE END
点赞7 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容