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

Laravel合并3个查询结果后调用paginate()报错:数组无法调用成员函数

问题原因

你当前的写法错误在于:get()方法会直接执行SQL并返回Collection集合对象,而paginate()是Laravel查询构建器(QueryBuilder)的方法,集合没有这个方法,所以调用merge_d_v_r->all()->paginate(20)会报错。

解决方案

优先推荐在数据库层面完成合并和分页,性能更优,同时符合Laravel的分页逻辑:

方案一:数据库层面合并查询(推荐)

将三个查询的条件合并,用CASE WHEN实现和你原逻辑一致的排序优先级(钻石广告→VIP广告→普通广告,同类型按对应pos字段升序),然后直接调用paginate():

$ads = AdModel::where('status', 1)
    ->where('category_id', $this_category_id)
    ->where('moderation', 0)
    ->orderByRaw("
        CASE
            WHEN ad_diamond = 1 THEN 0
            WHEN ad_vip = 1 THEN 1
            ELSE 2
        END,
        CASE
            WHEN ad_diamond = 1 THEN ad_diamond_pos
            WHEN ad_vip = 1 THEN ad_vip_pos
            ELSE ad_pos
        END ASC
    ")
    ->paginate(20);

$data['all_union_ads'] = $ads;

方案二:集合层面手动分页(仅适用于复杂内存操作场景)

如果必须在内存中合并集合后分页,可使用LengthAwarePaginator手动构建分页实例:

// 先获取符合条件的总记录数
$total = AdModel::where('status', 1)
    ->where('category_id', $this_category_id)
    ->where('moderation', 0)
    ->count();

// 获取当前页码,默认第1页
$page = request()->get('page', 1);
$perPage = 20;
$offset = ($page - 1) * $perPage;

// 查询各类型广告,普通广告需按分页剩余容量截取
$ads_diamond = AdModel::where('status', 1)
    ->where('category_id', $this_category_id)
    ->where('moderation', 0)
    ->where('ad_diamond', 1)
    ->orderBy('ad_diamond_pos', 'asc')
    ->get();

$ads_vip = AdModel::where('status', 1)
    ->where('category_id', $this_category_id)
    ->where('moderation', 0)
    ->where('ad_vip', 1)
    ->orderBy('ad_vip_pos', 'asc')
    ->get();

$defaultTake = $perPage - $ads_diamond->count() - $ads_vip->count();
$ads_default = AdModel::where('status', 1)
    ->where('category_id', $this_category_id)
    ->where('moderation', 0)
    ->where('ad_diamond', 0)
    ->where('ad_vip', 0)
    ->orderBy('ad_pos', 'asc')
    ->skip($offset)
    ->take($defaultTake > 0 ? $defaultTake : 0)
    ->get();

// 合并集合
$mergedAds = $ads_diamond->merge($ads_vip)->merge($ads_default);

// 手动创建分页器
$paginator = new Illuminate\Pagination\LengthAwarePaginator(
    $mergedAds,
    $total,
    $perPage,
    $page,
    ['path' => request()->url(), 'query' => request()->query()]
);

$data['all_union_ads'] = $paginator;

注意:方案二需要处理分页容量的截取逻辑,避免普通广告数量超出分页限制,性能不如方案一,仅当你有必须在内存中处理数据的场景时使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 10:54:33