Laravel中Decimal字段从数据库读取为字符串的解决方法
Laravel中Decimal字段返回字符串的解决方法
Laravel从数据库读取decimal类型的price字段时,默认会返回字符串(避免浮点数精度丢失),如果需要转为数值类型,可通过以下几种方式处理:
1. 模型字段转换(最推荐)
在对应模型中定义$casts属性,指定字段的转换类型:
class Product extends Model { protected $casts = [ // 转为浮点型 'price' => 'float', // 或者指定精度的decimal类型(Laravel会处理为数值) // 'price' => 'decimal:2' ]; }
设置后,从数据库读取price时会自动转为对应数值类型,存入时也会自动处理格式。
2. 自定义访问器
如果需要更灵活的转换逻辑(比如格式化输出),可以给字段添加访问器:
class Product extends Model { public function getPriceAttribute($value) { // 直接转为浮点型 return (float)$value; // 或者保留两位小数返回字符串(按需选择) // return number_format($value, 2, '.', ''); } }
访问器会自动覆盖字段的默认取值逻辑,每次读取$product->price时都会执行转换。
3. 查询时手动转换
针对单次查询场景,可在查询构造器中用DB::raw或selectRaw直接转换字段:
use Illuminate\Support\Facades\DB; $products = Product::select( 'id', 'name', DB::raw('CAST(price AS DECIMAL(10,2)) AS price') )->get();
这种方式不需要修改模型,适合临时的转换需求。
4. 全局批量处理(Laravel 8+)
如果多个模型都有decimal字段需要转换,可在AppServiceProvider中定义全局宏:
use Illuminate\Database\Query\Builder; public function boot() { Builder::macro('castDecimals', function () { return $this->get()->map(function ($item) { foreach ($item->getAttributes() as $key => $value) { $castType = $item->getCasts()[$key] ?? ''; if (str_contains($castType, 'decimal')) { $item->{$key} = (float)$value; } } return $item; }); }); }
使用时只需在查询链中调用:
$products = Product::query()->castDecimals()->get();
内容的提问来源于stack exchange,提问作者Misael
相关产品推荐
相关产品推荐

