You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel scopeFilter过滤查询如何正确传递两个参数?

问题原因
  • 第一个参数数量报错:Laravel自带的when()方法只会给传入的闭包回调传递2个固定参数,第一个是当前的查询构建器实例,第二个是when()第一个判断条件的真值(也就是你传入的$filters['mealType']的值),框架不会自动把serviceDate作为第三个参数注入闭包,你在闭包上声明3个入参,自然会报参数不足的错误。
  • 第二个未定义数组键报错:你写的($filters['mealType'] && $filters['serviceDate']) ?? null逻辑有误。空合并运算符??仅在左侧整个表达式返回null时才会走兜底值,但如果$filters数组里根本没有mealType键,直接访问$filters['mealType']会先抛出未定义键的错误,??根本来不及触发兜底。
正确写法

最简便的改法是用use关键字,把闭包需要用到的外部变量引入作用域,不需要在闭包的参数列表里声明这些外部变量:

public function scopeFilter($query, array $filters)
{
    $query
        ->when($filters['mealType'] ?? null, function ($query, $mealType) use ($filters) {
            $serviceDate = $filters['serviceDate'] ?? null;
            $query->whereDoesntHave('student_meals', fn ($query) => 
                $query->where('meal_type_id', $mealType)
                    ->where('void', false)
                    // 如果serviceDate有值才加日期条件,和你之前硬编码逻辑保持一致
                    ->when($serviceDate, fn($q) => $q->where('date_served', $serviceDate))
            );          
        });
}

如果你要求必须同时传入mealType和serviceDate才触发这段过滤逻辑,可以先把两个参数提前安全取出,再做判断,从根源避免未定义键报错:

public function scopeFilter($query, array $filters)
{
    $mealType = $filters['mealType'] ?? null;
    $serviceDate = $filters['serviceDate'] ?? null;

    $query
        ->when($mealType && $serviceDate, function ($query) use ($mealType, $serviceDate) {
            $query->whereDoesntHave('student_meals', fn ($query) => 
                $query->where('meal_type_id', $mealType)
                    ->where('void', false)
                    ->where('date_served', $serviceDate)
            );          
        });
}

注意:PHP闭包默认不能直接访问父作用域的变量,需要用use关键字显式引入要使用的外部变量,这是PHP本身的语法规则,和Laravel框架无关。

内容的提问来源于stack exchange,提问作者user19106040

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 10:36:43