
本文详解如何在 MySQL 的 JSON_REPLACE() 函数中正确引用含连字符(如 social-enable)的 JSON 键名,避免“Invalid JSON path expression”错误,并提供 CodeIgniter 框架下的安全写法与实践建议。
本文详解如何在 mysql 的 `json_replace()` 函数中正确引用含连字符(如 `social-enable`)的 json 键名,避免“invalid json path expression”错误,并提供 codeigniter 框架下的安全写法与实践建议。
在 MySQL 中操作 JSON 字段时,路径表达式(JSON Path)需严格遵循语法规范。当目标键名包含特殊字符(如连字符 -、空格、点号 . 或以数字开头)时,不能直接写作 $.settings.social-enable——因为 social-enable 不是合法的 ECMAScript 标识符(identifier),MySQL 会将其解析为 social 减去 enable,导致路径解析失败,并在错误提示中指出“around character position 27”(即 social-enable 中的 - 所在位置)。
✅ 正确做法是:将含特殊字符的键名用双引号包裹,并在 JSON 路径中使用 ."key-name" 语法。
根据 MySQL 官方文档,JSON 路径中的键名必须是双引号字符串(如 "social-enable")或合法标识符(如 country、state)。因此,原路径:
'$.settings.social-enable' ❌ 错误:social-enable 非法标识符
应修正为:
'$.settings."social-enable"' ✅ 正确:双引号明确界定键名
在 CodeIgniter 4 的 Query Builder 中,需注意 PHP 字符串转义。由于 SQL 表达式作为字符串传入 set() 方法,且启用了 false 参数(禁用自动转义),我们必须对双引号进行 PHP 层面的转义:
$builder = $this->db->table('users');
$builder->where('id', 2)
->set('information', "JSON_REPLACE(information, '$.settings.\"social-enable\"', '0')", false);
$builder->update();? 关键细节说明:
- 外层使用双引号定义 PHP 字符串,内部 $.settings."social-enable" 的双引号需用反斜杠转义:\"
- 单引号 '0' 作为新值,保持原样(MySQL 字符串字面量)
- false 参数确保该表达式被原样插入 SQL,不被 CodeIgniter 自动加引号或转义
? 补充验证建议(可选): 执行前可在 MySQL CLI 或 Adminer 中手动测试路径有效性:
SELECT JSON_EXTRACT('{"settings": {"social-enable": "1"}}', '$.settings."social-enable"');
-- 返回: "1"
SELECT JSON_REPLACE('{"settings": {"social-enable": "1"}}', '$.settings."social-enable"', '0');
-- 返回: {"settings": {"social-enable": "0"}}⚠️ 注意事项:
- 若 JSON 字段嵌套层级深或键名动态生成,建议先用 JSON_VALID() 校验数据完整性;
- 避免在路径中混用单引号和未转义双引号,易引发 SQL 解析错误;
- CodeIgniter 中若启用查询日志($this->db->enableQueryLog()),可快速定位拼接后的原始 SQL,辅助调试;
- 对于频繁更新的 JSON 子字段,考虑是否更适合拆分为独立数据库列(如 settings_social_enable TINYINT(1)),兼顾性能与可维护性。
总结:MySQL JSON 路径不是简单“点号分隔”,而是受 ECMAScript 标识符规则约束的表达式语言。牢记——所有非标准键名,必须用 ."key-name" 显式引用。一次正确的路径书写,即可彻底规避 Invalid JSON path expression 类错误。










