Laravel 8 + PHP 7.4 写入MySQL数据库时出现垃圾值问题求助
问题分析与解决方案
我之前遇到过几乎一模一样的问题,折腾了好一阵才搞定,给你分享下我的排查思路和解决方案:
核心原因推测
这个问题的根源大概率和 PHP 7.4 对大整数的处理逻辑变化 以及 Laravel 8 在该PHP版本下的数据库驱动兼容性有关:
- PHP 7.4的整数溢出处理调整:PHP在处理超过原生
int类型最大值(64位系统下是9223372036854775807)的数字时,会自动转为float类型。虽然你给出的product_id和inventory_id数值没超过这个上限,但部分环境下(比如某些特定的mysqlnd扩展版本),Laravel的查询构建器在PHP7.4下会错误地将这些大整数当成浮点数处理,导致精度丢失,最终存入数据库的就是被截断/篡改后的“垃圾值”。 - 数据库字段类型不是问题:你已经试过把字段改成
bigint(100)甚至varchar(255)都没用,这说明数据在从PHP传输到MySQL的过程中就已经被篡改了,和数据库字段类型无关。
可行的解决办法
试试下面几个方案,应该能解决问题:
强制以字符串形式传递大整数:
创建模型时,把大数字用字符串包裹,避免PHP自动转换类型:$product = Product::create([ 'product_id' => '6791044858042', 'inventory_id' => '42309695242426' ]);这样数据库驱动会按字符串类型传递数据,不会出现精度丢失。
在模型中定义属性类型转换:
在Product模型里添加类型转换规则,强制将这两个字段按字符串处理:protected $casts = [ 'product_id' => 'string', 'inventory_id' => 'string', ];这样Laravel在处理数据时会自动把数值转为字符串,从根源上避免类型转换问题。
检查并更新
mysqlnd扩展:
部分旧版本的mysqlnd在PHP7.4下对大整数的处理存在bug,尝试将mysqlnd更新到最新稳定版,或者临时切换到mysqli驱动测试下。临时回退PHP版本(应急方案):
你已经验证过回退到PHP7.3问题消失,如果上面的方案都无法快速解决,暂时回退版本也是个可行的应急办法。
验证步骤(辅助排查)
你可以在保存前打印变量的类型,确认是否被意外转为浮点数:
$productId = 6791044858042; var_dump($productId); // 如果输出是float,那就是类型转换导致的问题
如果输出是float,那说明PHP自动把大整数转成了浮点数,这时候必须用字符串形式传递数据才能解决问题。
内容的提问来源于stack exchange,提问作者Siva
相关产品推荐
相关产品推荐

