CodeIgniter(PHP)数组转JSON存入数据库存储值异常问题求助
问题原因
数据库里存储"Array"字符串的核心原因非常明确:你调用json_encode时传入的根本不是打印出来的二维数组,而是已经被PHP隐式转换为字符串Array的变量。
PHP存在一个隐式类型转换的特性:只要把数组类型变量当做字符串使用——比如放在双引号内做变量插值、和其他字符串直接拼接、传入要求字符串类型参数的函数,旧版本PHP不会抛出致命错误(甚至不会报警告),会直接把数组转换为字面量字符串Array。此时再对这个字符串调用json_encode,得到的自然就是JSON格式的字符串"Array",和你数据库里的存储结果完全匹配。
绝大多数开发者踩这个坑都是以下几种场景:
- 写代码手滑,给
json_encode的参数套了双引号,写成了json_encode("$product1"),双引号内的数组变量会被自动解析为字符串,直接触发上述隐式转换 - 打印
$product1的代码和执行插入的代码之间,存在修改变量的逻辑:比如写了$product1 .= 其他字符串这类拼接操作、错误对二维数组调用implode()、同名变量被其他逻辑覆盖为字符串 - 少数情况是漏写了
json_encode,直接把数组传给insert方法,旧版本CodeIgniter的SQL转义逻辑遇到数组类型字段值不会报错,会直接转成Array字符串拼接到SQL语句中
排查与修复步骤
- 先在插入逻辑前加调试代码,不要靠猜测定位问题,直接查看变量实际值:
// 组装待插入数据 $insertData = [ 'orderstatus' => $orderstatus, // 增加JSON_UNESCAPED_UNICODE参数避免中文被转义为Unicode编码,注意不要给$product1加任何引号 'productname' => json_encode($product1, JSON_UNESCAPED_UNICODE) ]; // 调试输出,执行到此处会终止程序,直接打印结果 echo '<pre>'; var_dump($product1); // 确认此处类型为array,如果显示string(5) "Array"说明变量在之前就已经被转换坏了 var_dump($insertData['productname']); // 正常情况此处应该输出类似[{"id":8,"productname":"Couple Combo Sherwani",...}]的完整JSON字符串 if (json_last_error() !== JSON_ERROR_NONE) { var_dump(json_last_error_msg()); // 如果json_encode执行失败,此处会输出具体错误原因,比如存在非法编码字符 } die; // 调试通过后再放开插入代码 // $this->db->insert('orders', $insertData);
- 根据调试结果对应修复即可:
- 如果打印
$product1已经是字符串Array:往前排查代码,找到把数组当字符串处理的位置删除即可,最常见的就是多余的引号、非法字符串拼接、错误的数组处理函数 - 如果
$product1是正常数组,但编码后结果为"Array":检查json_encode的参数是不是加了多余的引号、是不是套了strval()这类强制转字符串的函数,修正为直接传入数组变量 - 如果
json_encode返回布尔值false:根据错误提示修复数组问题,比如存在非法UTF-8字符就先做编码转换,存在资源类型值就移除
- 注意事项
建议将productname字段类型设置为TEXT或者LONGTEXT,避免JSON内容过长被截断;CodeIgniter 3及以上版本会自动对插入值做转义防护,不需要额外调用addslashes之类的函数处理。
内容的提问来源于stack exchange,提问作者ZNO
相关产品推荐
相关产品推荐

