CodeIgniter 4 不原生支持 JSON 字段自动序列化,需手动 json_encode() 写入或用 JSON_SET/jsonb_set 局部更新;须确保字段为 JSON/JSONB 类型,并注意路径存在性与 NULL 处理。

CodeIgniter 4 本身不原生支持 JSON 字段的自动序列化与反序列化(不像 Laravel 的 $casts),更新 JSON 类型字段时需手动处理 PHP 数组与 JSON 字符串之间的转换。关键在于:**确保传入数据库的是合法 JSON 字符串,且更新逻辑能被正确识别和执行**。
直接赋值 JSON 字符串(推荐用于简单场景)
若你已准备好结构清晰的数组,最稳妥的方式是显式 json_encode() 后写入:
- 在控制器中构造数据,例如:
$data = ['status' => 'done', 'attempts' => 2]; - 转为字符串:
$jsonStr = json_encode($data, JSON_UNESCAPED_UNICODE); - 通过模型或查询构建器更新:
$this->model->update($id, ['config' => $jsonStr]); - 注意:确保数据库字段类型为
JSON(MySQL)或JSONB(PostgreSQL),否则可能存为文本或报错
使用 Query Builder 执行局部更新(MySQL 5.7+)
当只需修改 JSON 中某个键(如 $.status),避免读取-修改-重写整段 JSON,可用 JSON_SET:
- 用
$builder->setQuery()或原生 SQL 执行:UPDATE table SET config = JSON_SET(config, '$.status', 'failed') WHERE id = ? - 务必加
WHERE条件,防止误更新;建议配合JSON_VALID(config)过滤无效 JSON 数据 - 若路径父级可能缺失(如
$.user.role中user不存在),JSON_SET不会自动创建,需先用COALESCE(config, '{}')提供默认空对象
模型层封装 JSON 更新逻辑(提升复用性)
为避免重复编码,可在模型中添加辅助方法:
- 定义一个
updateJsonField()方法,接收记录 ID、字段名、路径和新值 - 内部拼接
JSON_SET表达式,并调用$this->db->query() - 示例:
$this->updateJsonField($id, 'config', '$.retry_count', 3); - 搭配事务使用更安全:
$this->db->transStart(); ... $this->db->transComplete();
PostgreSQL 用户请用 jsonb_set
PostgreSQL 没有 JSON_SET,但 jsonb_set() 更灵活:
- 语法:
jsonb_set(data, '{user,role}', '"admin"', true)—— 第四个参数true表示自动创建缺失路径 - 字符串值必须是 JSON 格式,所以要写成
'"admin"'(带双引号的字符串) - 若字段可能为
NULL,用COALESCE(data, '{}'::jsonb)避免错误


















