ci3中关闭strict mode的两种可靠方式是在database.php配置数组中设'stricton'=>false,或连接后执行$this->db->query('set sql_mode = ""');ci4需在dsn末尾加;strict=0。

CI3 中关闭 strict mode 的两种可靠方式
CodeIgniter 3 默认启用 MySQL 严格模式,一旦插入空字符串到 NOT NULL 字段、时间格式非法或数值超限,整批操作直接失败,且错误提示不指明具体哪一行出问题。必须主动禁用才能让批量写入(如 insert_batch())稳定运行。
- 推荐在数据库配置数组中加
'stricton' => FALSE,位置在application/config/database.php的$db['default']数组内,和'hostname'、'username'并列 - 若需动态控制(比如仅对某次连接关 strict),可在连接建立后立即执行:
$this->db->query('SET sql_mode = ""');,但注意该语句只对当前连接生效 - 别碰
$this->db->transStrict(FALSE)—— 这是事务严格模式开关,和 SQL 层 strict mode 完全无关,设了也没用
CI4 中通过 DSN 关闭 strict mode
CodeIgniter 4 不再用 PHP 数组配数据库,strict mode 控制必须写进 DSN 字符串。默认 DSN 里没 strict=0,就会继承 MySQL 服务端设置,大概率触发批量失败。
- 修改
.env文件中的database.default.DSN,在末尾追加;strict=0,例如:mysql:host=localhost;dbname=app;charset=utf8mb4;strict=0 - 如果 DSN 已含其他参数(如
unix_socket),确保用分号;分隔,不能用 & 或 ? - 改完必须清空
writable/cache/下的缓存文件,否则旧 DSN 仍被读取 - 验证是否生效:连接后执行
$this->db->query('SELECT @@sql_mode')->getRow();,返回结果为空或不含STRICT_TRANS_TABLES即成功
strict mode 关着也不代表万事大吉
关 strict 是批量插入的前提,不是万能解药。它只是把“整批中止”降级为“单条跳过”,但跳过的那条数据依然丢了,且不会报错——你得自己检查影响行数或逐条验证输入。
-
insert_batch()和insertBatch()都不返回失败的具体索引,只返回总影响行数,和传入数组长度对比才能发现丢数据 - 空字符串插
VARCHAR NOT NULL字段时,strict 关了会转成''存进去;但插INT NOT NULL时,空字符串会被转成0,这可能不是你想要的业务含义 - 某些云数据库(如阿里云 RDS)强制开启部分 strict 行为,仅改应用层配置无效,得去控制台调实例参数
为什么不能靠 $this->db->transOff() 关 strict
这个方法名有强误导性。“trans” 指 transaction,不是 “strict”。调用它只会关闭事务自动管理,对 SQL 模式零影响,还可能导致后续 transStart() 失效——属于典型的名字误判坑。
-
$this->db->transOff()的作用是让框架不再自动 wrapBEGIN/COMMIT/ROLLBACK,和 MySQL 的sql_mode完全无关 - 如果你在关 strict 前误调了它,又没手动
transStart(),那insertBatch()就退化成逐条 auto-commit,IO 压力翻几十倍 - 查文档确认:
transOff()只在 CI3 文档里有明确说明,CI4 已移除该方法,代码里调用会直接报错











