PHP MySQL更新model_type字段时反斜杠丢失未得预期结果怎么办
问题原因
反斜杠\是绝大多数关系型数据库(比如MySQL)默认的转义标识符,不属于普通字符:
- 当你直接在SQL语句中写入
'App\Models\User'时,数据库解析SQL语法的阶段会把反斜杠识别为转义标记,由于\M、\U不属于数据库预定义的有效转义序列(比如\n代表换行、\'代表单引号这类才是有效转义),解析时反斜杠会被直接丢弃,最终存入字段的值就变成了AppModelsUser。 - 如果你是在PHP、Python等编程语言中拼接SQL语句执行,还会多一层转义消耗:编程语言本身解析字符串字面量时就会先处理掉一层反斜杠,真正传到数据库的SQL语句里反斜杠已经丢失了,最后存储结果自然不对。
解决方法
你可以根据自己的使用场景选对应方案:
- 直接手写SQL执行时,把字符串里的每个反斜杠双写,用
\\代表一个实际要存储的反斜杠,数据库解析后会正确存入单个反斜杠,修正后的SQL语句如下:
UPDATE model_has_roles SET model_type='App\\Models\\User';
- 如果你是在业务代码中执行更新操作,不要手动拼接SQL字符串,改用数据库提供的预处理参数绑定能力,驱动会自动处理特殊字符转义,完全不需要手动处理反斜杠。你用到的
model_has_roles是Laravel Permission权限组件的表,以Laravel框架场景为例,直接用模型类常量传值即可:
// 直接传PHP类名常量,框架自动处理转义,不会出现字符丢失 \Spatie\Permission\Models\Role::query()->update(['model_type' => \App\Models\User::class]);
- 临时方案(不推荐生产环境使用):当前数据库会话执行
SET sql_mode='NO_BACKSLASH_ESCAPES';,关闭反斜杠转义规则后,反斜杠会被识别为普通字符,原SQL语句可以正常执行,但这个配置会影响当前会话所有SQL的解析逻辑,容易引发其他不可预期的问题。
内容的提问来源于stack exchange,提问作者Abdullah Al Noman
相关产品推荐
相关产品推荐

