CI3中执行原生SQL插入须遵循安全、明确、可控原则:必须显式指定字段名;字符串用单引号并转义,NULL不加引号;批量插入用标准多值语法;emoji需utf8mb4字符集支持。

CI3(CodeIgniter 3)中执行原生 SQL 插入语句,核心原则是:**安全、明确、可控**。它不强制你用 Query Builder,但一旦选择写原生 INSERT,就必须规避硬编码、SQL 注入、字段错位、字符集异常等常见问题。下面从实际开发角度,讲清怎么写才规范、可靠、可维护。
必须显式指定字段名
哪怕表结构简单,也绝不能用 INSERT INTO table VALUES (...) 这种省略字段的写法。原因很直接:字段顺序可能随 ALTER TABLE 变动,脚本一升级就崩。
- ✅ 正确写法:
INSERT INTO user (id, username, email, created_at) VALUES (1, 'admin', 'admin@example.com', NOW()) - ❌ 危险写法:
INSERT INTO user VALUES (1, 'admin', 'admin@example.com', NOW())(依赖建表时的列序,脆弱)
值要适配数据类型,尤其注意 NULL 和字符串边界
MySQL 对空值、空字符串、时间、数字的处理很严格。CI3 不做自动类型转换,写错就会报错或存入异常值。
- 字符串值必须加单引号,且内容需经
$this->db->escape()或使用查询绑定(推荐) - NULL 值直接写
NULL,不要加引号;而空字符串''是合法字符串,和 NULL 语义不同 - 时间字段优先用
NOW()或'2026-08-13 12:00:00'字面量,避免 PHP 时间戳转 MySQL 时间出错
批量插入要用标准多值语法,别拼接字符串
一次插 10 条,绝不该循环 10 次 query()。CI3 支持原生多行 INSERT,既高效又减少连接开销。
- ✅ 推荐:
INSERT INTO log (action, user_id, ip, created_at) VALUES ('login', 5, '192.168.1.100', NOW()), ('view', 5, '192.168.1.100', NOW()), ('logout', 5, '192.168.1.100', NOW()) - ⚠️ 避免手动拼接:
"VALUES (" . implode('),(', $rows) . ")"—— 易引入引号/转义漏洞
字符集与 emoji 支持要提前确认
如果字段可能存 emoji(如昵称、评论),仅靠 VARCHAR(255) 不够。必须确保:
- 数据库、表、字段都设为
utf8mb4字符集(不是旧版utf8) - CI3 的数据库配置中指定
'char_set' => 'utf8mb4'和'dbcollat' => 'utf8mb4_unicode_ci' - 否则插入 ? 或 ? 会变成 ??? 或直接报错 “Incorrect string value”

















