如何避免向MySQL数据库插入时小数被舍入
解决经纬度插入/更新时被强制舍入的问题
我之前处理过类似的经纬度存储bug,咱们一步步拆解排查:
1. 先检查模型的$casts属性
这是最容易踩的坑!如果你的Centre模型里错误地把lat或lng设置成了整数类型转换,不管你传入什么小数,都会被强制转成整数,直接导致舍入。
打开你的Centre.php模型,看看有没有类似代码:
protected $casts = [ 'lat' => 'integer', 'lng' => 'integer', ];
如果有,把它改成对应decimal类型:
protected $casts = [ 'lat' => 'decimal:8', 'lng' => 'decimal:8', ];
或者直接删掉这两个字段的casts配置,Laravel会自动匹配数据库字段类型处理。
2. 确认实际传入的数值是否正确
你示例里用了硬编码的51.4988814,但实际业务中是不是从$centre->acf获取的?比如$centre->acf->lat。
可以在执行updateOrCreate前打印数值,确认它不是整数:
dd($centre->acf->lat, $centre->acf->lng); // 检查输出是不是51.4988814和-0.1415936,而非51和0
如果WordPress的ACF字段类型设成了「整数」而非「小数」,那取出来的自然是整数,这种情况要去后台修改ACF字段的类型为带小数的数字类型。
3. 查看Laravel实际执行的SQL语句
有时候代码里的数值看起来正确,但实际传给数据库的可能有问题。可以开启查询日志验证:
DB::enableQueryLog(); $centre = Centre::updateOrCreate( ['wordpress_id' => $centre->ID], [ 'name' => $centre->post_title, 'postcode' => $centre->acf->postcode, 'lat' => 51.4988814, 'lng' => -0.1415936 ] ); dd(DB::getQueryLog());
如果日志里的SQL中lat值是51而非51.4988814,问题出在PHP代码层面(比如模型casts、数据来源);如果SQL值正确但数据库存的是51.00000000,再回头检查数据库字段(不过你提供的SHOW CREATE TABLE看起来是正常的)。
4. 手动测试数据库插入
可以直接在数据库执行插入语句验证:
INSERT INTO centres (wordpress_id, name, lat, lng) VALUES (123, 'Test Centre', 51.4988814, -0.1415936);
然后查询这条记录,正常情况下lat应该是51.49888140(小数位8位会补一个0)。如果手动插入没问题,那100%是Laravel代码层面的问题。
内容的提问来源于stack exchange,提问作者Gazz
相关产品推荐
相关产品推荐

