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

Laravel DB查询报Trying to get property 'id' of non-object错误排查

问题根因

触发Trying to get property 'id' of non-object报错的直接原因是:遍历全量产品时,存在部分产品没有匹配到is_xml=1的变体价格记录。
查询构造器的first()方法在找不到匹配数据时会返回null,此时直接访问$vprice->id本质是在访问null值的属性,必然触发非对象错误。你之前调试时能拿到正常返回结果,是因为dd()会在第一次命中有效结果的循环轮次直接终止程序,没有执行到后续无匹配数据的产品遍历逻辑,所以没复现报错。

修复方案

基础修复:增加判空逻辑

最直接的改法是在访问属性前先判断查询结果是否为空,同时可以在查询时指定只拉取需要的id、price字段,减少不必要的数据传输:

$products = Product::all();
foreach($products as $pr){
    $vprice = DB::table('product_variation_prices')
        ->select('id', 'price')
        ->where('product_id', $pr->id)
        ->where('is_xml', 1)
        ->first();
    
    // 无匹配记录时跳过当前产品的后续逻辑
    if (is_null($vprice)) {
        // 如需排查脏数据,可以在这里打印对应产品ID
        // dump("产品ID:{$pr->id} 无匹配的xml变体价格");
        continue;
    }

    // 此处可安全访问属性
    $variationId = $vprice->id;
    $variationPrice = $vprice->price;
    // 编写后续业务逻辑
}

性能优化:避免N+1查询问题

你当前循环内反复查库的写法属于典型的N+1查询问题,产品量级上来后会产生大量数据库请求,拖慢接口性能,可以用一次查询拉取所有需要的变体数据再分组匹配:

// 一次性拉取所有符合条件的变体价格,按产品ID分组
$variationPrices = DB::table('product_variation_prices')
    ->select('id', 'price', 'product_id')
    ->where('is_xml', 1)
    ->whereIn('product_id', Product::pluck('id'))
    ->get()
    ->groupBy('product_id');

$products = Product::all();
foreach($products as $pr){
    // 从内存已拉取的集合中匹配数据,无需重复查库
    $vprice = $variationPrices->get($pr->id)?->first();
    if (is_null($vprice)) {
        continue;
    }
    // 后续正常使用$vprice->id、$vprice->price即可
}

注:上述代码中的?->是PHP8.0及以上版本支持的空安全操作符,若项目运行在PHP7.x环境,将对应取值逻辑替换为isset($variationPrices[$pr->id]) ? $variationPrices[$pr->id]->first() : null即可兼容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:09:20