Laravel中出现Attempt to read property "price" on null报错如何解决?
错误原因
- 关联关系定义错误:
Order模型无需直接关联Product,你的orders表没有product_id字段,该关联本身无效。正确的关联逻辑是:订单关联多个订单项,订单项关联单个商品。 - 商品获取逻辑错误:你代码中
$product = Product::all()拿到的是所有商品的集合,不是当前循环对应的单个商品,$order->$product->price的写法完全不符合Laravel关联调用规则。 - 存在语法错误:创建
Orderitem时'total' => 3,''末尾多了多余的单引号,会触发语法报错。 - 金额计算逻辑硬编码:订单总价、订单项总价都写死固定值,没有按实际单价*数量计算。
修复方案
1. 修正模型关联
首先修改Order模型,删除无效的product关联,调整订单项关联命名更符合规范:
protected $table = "orders"; protected $fillable = [ 'user_id', 'total', ]; public function user() { return $this->belongsTo(User::class); } public function orderitems() { return $this->hasMany(Orderitem::class); }
在你未粘贴的Orderitem模型中,添加和Product的关联:
// Orderitem 模型代码 protected $fillable = [ 'order_id', 'product_id', 'quantity', 'price', 'total' ]; public function order() { return $this->belongsTo(Order::class); } public function product() { return $this->belongsTo(Product::class); }
调整Product模型关联,删除无效的订单关联,改为关联订单项:
use HasFactory; protected $table = "products"; protected $fillable = [ 'name', 'price', ]; public function orderitems() { return $this->hasMany(Orderitem::class); }
2. 修正控制器store方法
public function store(Request $request) { // 先做参数校验,避免非法参数报错 $validated = $request->validate([ 'user_id' => 'required|exists:users,id', 'product_id' => 'required|array', 'product_id.*' => 'exists:products,id', 'quantity' => 'required|array', 'quantity.*' => 'required|integer|min:1' ]); // 创建初始订单,总价后续计算更新 $order = Order::create([ 'user_id' => $validated['user_id'], 'total' => 0, ]); $orderTotal = 0; // 遍历商品列表创建订单项 foreach ($validated['product_id'] as $index => $productId) { $product = Product::findOrFail($productId); $quantity = $validated['quantity'][$index]; $itemTotal = $product->price * $quantity; $order->orderitems()->create([ 'product_id' => $productId, 'quantity' => $quantity, 'price' => $product->price, 'total' => $itemTotal ]); $orderTotal += $itemTotal; } // 更新订单实际总价 $order->update(['total' => $orderTotal]); return redirect()->route('orders.index'); }
逻辑说明
- 新增参数校验逻辑,避免参数缺失、非法ID导致的报错
- 改用
foreach遍历商品,不会出现下标越界问题 - 每次循环获取当前对应ID的商品,直接读取价格,不需要通过订单关联调用
- 自动计算订单项总价、订单总价,无需硬编码数值
- 通过关联关系创建订单项,无需手动传入
order_id,降低出错概率
内容的提问来源于stack exchange,提问作者user16160492
相关产品推荐
相关产品推荐

