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

Laravel Eloquent获取不重复随机行及whereNotIn报错求助

多页问卷随机获取未展示数据的Eloquent解决方案

错误原因

你遇到的Nested arrays may not be passed to whereIn method错误,是因为$this->qs本身就是一维数组(比如[1,3,8]),但你在whereNotIn里用[$this->qs]把它又包了一层,变成了二维数组[[1,3,8]],而Eloquent的whereNotIn方法要求传入一维数组作为排除条件,所以触发了这个错误。

另外原有逻辑存在漏洞:先随机生成ID再判断是否在排除列表,可能会抽到已经展示过的ID,导致重复展示或者无效查询。

最优实现方案

直接让数据库查询时排除已展示的ID,并随机返回一条未展示的记录,既避免重复又更高效:

// 从Session获取已展示的问卷ID数组,默认空数组
$shownIds = $request->session()->get('arrayOfQs', []);

// 查询未展示的随机问卷
$question = Ctest::whereNotIn('id', $shownIds)
    ->inRandomOrder()
    ->first();

if ($question) {
    // 将新问卷ID加入已展示数组并更新Session
    $shownIds[] = $question->id;
    $request->session()->put('arrayOfQs', $shownIds);
} else {
    // 所有问卷都已展示完毕的处理逻辑
    // 比如重置Session或者提示用户
    $request->session()->forget('arrayOfQs');
    // return response()->json(['message' => '所有问卷已展示完毕']);
}

// 后续处理$question...

保留随机数生成逻辑的修正方案

如果坚持要自己生成随机数,需先判断生成的ID是否在排除列表里,直到拿到未展示的ID,同时修正whereNotIn的参数:

$shownIds = $request->session()->get('arrayOfQs', []);
$randomId = $this->generateRandInt($request)['randomInt'];

// 循环直到拿到未展示的ID
while (in_array($randomId, $shownIds)) {
    $randomId = $this->generateRandInt($request)['randomInt'];
}

// 正确查询:直接传入一维数组$shownIds,不需要额外包裹
$question = Ctest::whereNotIn('id', $shownIds)
    ->find($randomId);

// 更新Session数组
$shownIds[] = $randomId;
$request->session()->put('arrayOfQs', $shownIds);

注意:这种方法在接近所有问卷都展示完时,可能会多次循环生成随机数,效率不如直接让数据库随机查询的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:13:21