
在 laravel 中向数据库 json 类型字段写入关联数组时,必须先将其序列化为字符串(如用 json_encode),否则会触发 “array to string conversion” 错误。
在 laravel 中向数据库 json 类型字段写入关联数组时,必须先将其序列化为字符串(如用 json_encode),否则会触发 “array to string conversion” 错误。
当你通过 HTTP 客户端(如 Http::get())从外部 API 获取国家数据,并尝试将嵌套结构(例如多语言名称 ['en' => 'United States', 'ka' => 'აშშ'])直接赋值给模型的 JSON 字段时,Laravel 默认不会自动序列化数组——即使该字段在数据库中定义为 JSON 类型(MySQL 5.7+ / PostgreSQL)或 TEXT(SQLite)。此时直接赋值数组会导致 PHP 尝试隐式转换,从而抛出 Array to string conversion 错误。
✅ 正确做法是:显式调用 json_encode() 将数组转为合法 JSON 字符串,再存入字段:
public function fetch()
{
$response = Http::get('https://api.example.com/countries');
// 确保请求成功且返回有效 JSON
if (!$response->successful()) {
throw new \Exception('API request failed: ' . $response->status());
}
$countries = $response->json(); // 推荐:直接用 ->json() 解析,比 json_decode(..., true) 更安全
foreach ($countries as $country) {
$api = new Country();
$api->code = $country['code'] ?? null;
// ✅ 关键:将多语言名称数组序列化为 JSON 字符串
$api->name = json_encode([
'en' => $country['name']['en'] ?? '',
'ka' => $country['name']['ka'] ?? ''
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$api->save();
}
return response()->json(['message' => 'Countries imported successfully'], 200);
}? 注意事项与最佳实践:
不要依赖模型自动 JSON 处理:Laravel 的 $casts = ['name' => 'json'] 仅在 读取 时自动反序列化;写入时仍需传入字符串(或让 Eloquent 自动处理——见下文进阶方案)。
-
推荐使用 $casts + 原生数组赋值(更优雅):
在 Country 模型中定义:protected $casts = [ 'name' => 'json', // 其他 JSON 字段... ];此时你可以直接赋值 PHP 数组,Eloquent 会在保存前自动调用 json_encode:
$api->name = ['en' => $country['name']['en'], 'ka' => $country['name']['ka']];
✅ 这是 Laravel 官方推荐方式,语义清晰、无需手动编码,且自动处理空值/特殊字符。
健壮性增强:添加 ?? 空合并操作符防止键不存在导致 Notice;使用 JSON_UNESCAPED_UNICODE 保留中文等 UTF-8 字符不被转义。
批量插入优化(可选):对大量数据,改用 Country::upsert() 或 insert() 避免 N+1 查询,提升性能。
总结:核心原则是——JSON 字段写入必须是字符串。要么手动 json_encode(),要么借助 $casts 让框架代劳。后者更符合 Laravel 的约定优于配置理念,也更安全、可维护。


















