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
相关产品推荐
相关产品推荐

