Laravel array_push合并查询后调用links()分页报错修复
问题根因
Call to a member function links() on array报错原因非常直接:
- Laravel的
paginate()方法返回的是LengthAwarePaginator分页实例,只有该实例可以调用links()方法渲染分页组件 - 现有代码用
array_push()把多次查询得到的独立分页对象塞进普通PHP数组$pro,最终传到视图的$pro是原生数组类型,不是分页实例,自然无法调用类成员方法links() - 现有写法还存在逻辑漏洞:循环内每次查询都单独调用
paginate(12),会生成多个互相独立的分页器,页码、数据总数统计完全割裂,就算不报错也无法实现正确的全局分页效果。
修复方案
不要在循环内部做分页,先收集全量符合条件的查询规则,组装成统一的查询构造器后最后执行一次分页即可。
后端代码修改
移除循环内的分页调用,先查询所有分类下商品对应的最大库存数,统一拼接查询条件后执行单次分页,参考代码如下:
public function searchProduct(Request $request) { $targetProductMap = []; // 该阶段仅查询匹配规则,不做分页 foreach ($catePro as $cateProCode) { $maxQtyList = DB::table('product') ->select(['product.prod_product_code', DB::raw('MAX(quab_quantity) AS qty')]) ->leftJoin('quantity_break', 'quab_product_code', '=', 'prod_product_code') ->where('prod_product_code', '=', $cateProCode->catpro_prod_code) ->get(); foreach ($maxQtyList as $item) { $targetProductMap[] = [ 'prod_code' => $item->prod_product_code, 'max_qty' => $item->qty ]; } } // 构建统一商品查询 $productQuery = DB::table('product') ->join('quantity_break', 'quab_product_code', '=', 'prod_product_code') ->join('supplier','supp_code','=','prod_supplier_code') ->select('prod_product_code','prod_supplier_code', 'product_name', 'prod_image1', 'prod_from_price', 'quab_quantity','supp_margin','prod_supp_margin','prod_seo_title') ->where('supp_flag','=','1') ->orderBy('supp_seq_no','ASC'); // 批量拼接筛选条件,匹配所有目标商品+对应最大库存 $productQuery->where(function($query) use ($targetProductMap) { foreach ($targetProductMap as $mapItem) { $query->orWhere(function($subQuery) use ($mapItem) { $subQuery->where('prod_product_code', '=', $mapItem['prod_code']) ->where('quab_quantity', '=', $mapItem['max_qty']); }); } }); // 统一执行分页,返回的结果就是可以直接调用links()的分页实例 $pro = $productQuery->paginate(12); $sysfromPrice = sysmaster::where('sysm_def_id','from_price')->first(); $subCateList = sub_category_one::where('suco_flag','1')->orderBy('suco_name')->get(); return view('search_product')->with([ 'subCateList' => $subCateList, 'pro' => $pro, 'subCate' => $subCate, 'cateInfo' => $cate, 'sysfromPrice' => $sysfromPrice, 'suppList' => $suppList ]); }
前端代码
原有前端分页调用代码不需要修改,可直接正常渲染:
{!! $pro->links() !!}
补充说明
- 分页逻辑必须在最终的全量结果集上统一执行,禁止在循环中多次调用
paginate(),否则必然出现页码错乱、数据重复/缺失的问题 - 遇特殊业务必须合并多个不同查询结果再分页的场景,不能直接用
array_push合并数组传参,需要手动实例化Illuminate\Pagination\LengthAwarePaginator类,传入合并后的数据集合、总条数、每页条数、当前页码等参数生成合法分页实例,再传给视图渲染。
内容的提问来源于stack exchange,提问作者Jerad
相关产品推荐
相关产品推荐

