Laravel品牌筛选功能失效,报错指向正常的分类函数
问题分析与修复:品牌筛选功能报错
Call to a member function products() on null 问题描述
实现分类和品牌筛选功能时,分类功能正常,但点击品牌链接触发错误:Call to a member function products() on null,报错指向品牌控制器方法中的->products()->paginate(12);代码行。
报错原因
- 路由与控制器参数不匹配:路由定义的参数是
{marque?},但控制器方法接收的参数是$slug,Laravel无法正确将URL中的参数值绑定到方法参数,导致$slug为null。此时Brand::where('slug', $slug)->first()返回null,调用products()方法自然触发错误。 - 未处理品牌不存在的场景:即使参数匹配,当传入的
slug对应的品牌不存在时,first()也会返回null,同样会触发调用products()的错误。
修复方案
1. 修正路由与控制器参数的一致性
确保路由参数名和控制器方法接收的参数名一致,两种可选方式:
方式一:修改路由参数名
// 品牌路由,将参数名从{marque?}改为{slug?} Route::get('catalogue/marque/{slug?}', 'App\Http\Controllers\CatalogueController@marque')->name('catalogue.marque');
方式二:修改控制器参数名
// 品牌函数,将参数从$slug改为$marque function marque($marque) { $products = \App\Models\Brand::where('slug', $marque) ->first() ->products()->paginate(12); // 其余代码保持不变 }
注:视图中路由参数使用的是['slug' => $brand->slug],因此优先选择方式一更适配现有视图代码。
2. 添加品牌不存在的异常处理
避免在null对象上调用方法,可通过两种方式处理:
方式一:使用firstOrFail()自动抛出404
function marque($slug) { // 当品牌不存在时自动抛出404异常 $brand = \App\Models\Brand::where('slug', $slug)->firstOrFail(); $products = $brand->products()->paginate(12); $categories = \App\Models\Category::all(); $brands = \App\Models\Brand::all(); return view('catalogue.index', compact('products', 'categories', 'brands')); }
方式二:手动判断并处理
function marque($slug) { $brand = \App\Models\Brand::where('slug', $slug)->first(); // 品牌不存在时返回404或自定义提示 if (!$brand) { abort(404, '该品牌不存在'); } $products = $brand->products()->paginate(12); $categories = \App\Models\Category::all(); $brands = \App\Models\Brand::all(); return view('catalogue.index', compact('products', 'categories', 'brands')); }
3. 处理可选参数的场景(路由带?)
路由中的{marque?}表示参数可选,若需要支持访问catalogue/marque不带参数的情况,需在方法中处理$slug为null的逻辑:
function marque($slug = null) { if ($slug) { $brand = \App\Models\Brand::where('slug', $slug)->firstOrFail(); $products = $brand->products()->paginate(12); } else { // 不带参数时的逻辑,例如返回所有商品 $products = \App\Models\Product::paginate(12); } $categories = \App\Models\Category::all(); $brands = \App\Models\Brand::all(); return view('catalogue.index', compact('products', 'categories', 'brands')); }
内容的提问来源于stack exchange,提问作者user23719376
相关产品推荐
相关产品推荐

