Laravel中跳过空值执行查询及套餐订阅校验问题
Laravel查询空值处理与业务场景解决方案
一、解决你的订阅提示业务问题
你当前的代码报错是因为当用户没有Deposit记录时,$sit会是null,直接访问$sit->plan_id就会触发“尝试访问null对象属性”的错误。其实不用先获取整个记录再判断,直接查询用户是否存在plan_id=8的Deposit记录会更高效,也能自然避免空值问题:
public function newbonus() { // 直接检查用户是否有plan_id为8的Deposit记录 $hasClaimedBonus = Deposit::where('user_id', Auth::user()->id) ->where('plan_id', 8) ->exists(); if ($hasClaimedBonus) { session()->flash('message', 'You have Claimed Free Bonus Already...'); } else { // 这里添加允许订阅的逻辑,比如创建新的Deposit记录等 } }
exists()方法会直接返回布尔值:如果存在符合条件的记录返回true,否则返回false,完全不需要处理null的情况,代码更简洁也更高效。
二、Laravel中跳过空值执行查询的通用方法
针对“跳过空值执行查询”的需求,分两种常见场景处理:
1. 构建查询时跳过空的条件参数
如果你的查询有多个可选参数(比如前端传的筛选条件可能为空),不想把空值作为查询条件,可以用when()方法或者条件判断来动态添加查询:
方式一:使用条件判断
$query = Deposit::query(); // 仅当$planId非空时,添加plan_id查询条件 if (!empty($planId)) { $query->where('plan_id', $planId); } // 同理处理其他可选参数 if (!empty($userId)) { $query->where('user_id', $userId); } $deposits = $query->get();
方式二:使用when()方法(更简洁)
when()方法会在第一个参数为true时执行闭包里的查询逻辑,非常适合动态构建查询:
$deposits = Deposit::when(!empty($planId), function ($query) use ($planId) { return $query->where('plan_id', $planId); }) ->when(!empty($userId), function ($query) use ($userId) { return $query->where('user_id', $userId); }) ->get();
2. 处理查询结果中的空值
如果确实需要获取模型实例,但担心返回null,可以用Laravel提供的optional()辅助函数,或者PHP的null安全运算符来避免报错:
方式一:optional()辅助函数
$sit = Deposit::where('user_id', Auth::user()->id)->first(); // 如果$sit是null,optional()会返回一个空对象,访问plan_id时不会报错,而是返回null if (optional($sit)->plan_id == 8) { session()->flash('message', 'You have Claimed Free Bonus Already...'); }
方式二:null安全运算符
$sit = Deposit::where('user_id', Auth::user()->id)->first(); // 使用?->运算符,当$sit为null时直接返回null,不会触发错误 if ($sit?->plan_id == 8) { session()->flash('message', 'You have Claimed Free Bonus Already...'); }
不过这种方式不如前面的exists()高效,因为还是会查询并返回整个模型实例,推荐优先用exists()来处理这类“是否存在”的判断场景。
内容的提问来源于stack exchange,提问作者Numair Qasim
相关产品推荐
相关产品推荐

