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

Laravel获取数据库价格值异常:为何{"price":80}改用value后存为null?

问题分析与解决方案

首先咱们拆解一下你遇到的两个问题,再给出对应的解决办法:

为什么first(['rates.price'])会得到{"price":80}?

当你调用first(['rates.price'])时,Eloquent返回的不是单纯的数值,而是一个Booking模型实例——哪怕你只指定了一个字段,它依然会封装成模型对象。当你直接把这个模型赋值给$bookings->price时,Laravel会自动将模型序列化成JSON/数组格式,所以最终存储的就是{"price":80}这种对象结构,而非你需要的double类型数值。

为什么换成value('rates.price')会返回null?

大概率是查询条件的问题,常见的几个可能性:

  1. 用户ID字段错误:Laravel默认用户表的主键是id,但你用了Auth::user()->userid,如果你的用户表主键不是userid,这个条件会直接导致查询无结果,进而value()返回null。
  2. 冗余条件导致无匹配:你加了where('bookings.park_area','=',$bookings->park_area),如果$bookings是你正要保存的新模型(还没写入数据库),或者park_area值为空,这个条件会让查询找不到匹配的记录。
  3. 字段引用的小坑:虽然你写了rates.price,但极少数情况下,Eloquent的value()方法在Join场景下可能对跨表字段的识别有问题,不过这个概率很低。

如何正确获取80这个数值?

给你三个可行的方案,按推荐程度排序:

方案1:从first()返回的模型中提取属性值

既然first()能拿到包含price的模型,直接提取属性值即可:

$duit = Booking::join('rates', 'bookings.park_area', '=', 'rates.areaid')
    ->where('bookings.user_id', '=', Auth::user()->id) // 这里改成id,除非你的用户主键确实是userid
    ->where('bookings.park_area', '=', $bookings->park_area)
    ->where('bookings.semester', '=', $bookings->semester)
    ->first(['rates.price']);

if ($duit) { // 先判断是否存在结果,避免报错
    $bookings->price = $duit->price; // 提取模型的price属性值
    $bookings->save();
}

方案2:排查并修复value()的查询问题

先确保查询条件正确,再用value()直接取数值:

$price = Booking::join('rates', 'bookings.park_area', '=', 'rates.areaid')
    ->where('bookings.user_id', '=', Auth::user()->id)
    ->where('bookings.park_area', '=', $bookings->park_area)
    ->where('bookings.semester', '=', $bookings->semester)
    ->value('rates.price');

if ($price !== null) {
    $bookings->price = $price;
    $bookings->save();
}

如果还是返回null,建议打印实际执行的SQL排查问题:

$query = Booking::join('rates', 'bookings.park_area', '=', 'rates.areaid')
    ->where('bookings.user_id', '=', Auth::user()->id)
    ->where('bookings.park_area', '=', $bookings->park_area)
    ->where('bookings.semester', '=', $bookings->semester)
    ->select('rates.price');

dd($query->toSql(), $query->getBindings()); // 打印SQL语句和绑定参数,检查是否符合预期

方案3:用Eloquent关联(最优雅的长期方案)

既然Bookings和Rates通过park_area与areaid关联,直接在Booking模型中定义关联关系:

// 在Booking模型文件中
public function rate()
{
    return $this->belongsTo(Rate::class, 'park_area', 'areaid');
}

然后直接通过关联获取价格:

// 确保$bookings已经有user_id、park_area、semester的有效值
$price = $bookings->rate->price ?? null;

if ($price !== null) {
    $bookings->price = $price;
    $bookings->save();
}

这种方式更符合Laravel的设计理念,代码也更简洁易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:51:51