codeigniter插入数据时,只有完全不包含字段才能触发数据库default约束;需用unset()或set()链式写法跳过空值字段,避免传null或空字符串导致默认值失效。

CodeIgniter 插入数据时,若某些字段传入 null 或空字符串(''),数据库可能报错或存入意外值(如 0、'0'、空字符串),而非你期望的默认值(如 NULL、当前时间、默认整数等)。关键在于区分「PHP 层不传字段」和「传了但值为空」——只有前者才会真正触发数据库的 DEFAULT 约束。
让数据库真正生效 DEFAULT 的前提
必须确保插入 SQL 中完全不包含该字段。CodeIgniter 的 $this->db->insert() 会把数组中所有键都生成为 SQL 字段,哪怕值是 null 或空字符串。所以不能靠“传 null”来触发默认值。
- 手动过滤掉不想插入的字段:用
unset()或array_filter()剔除空值键 - 使用
set()+set()链式写法,只对非空字段调用set() - 建表时明确设好
DEFAULT(如status TINYINT DEFAULT 1)并允许NULL(如需存 NULL)
用 set() 动态控制字段写入
比直接传数组更灵活,可配合条件判断跳过空字段:
$this->db->set('title', $data['title'])
->set('content', $data['content']);
if (!empty($data['publish_time'])) {
$this->db->set('publish_time', $data['publish_time']);
}
// created_at 不 set → 数据库用 DEFAULT CURRENT_TIMESTAMP
$this->db->insert('articles');
这样,publish_time 和 created_at 若未显式 set(),就不会出现在 INSERT 语句中,数据库自然用默认值。
统一预处理空值的辅助方法
在模型或基础类里封装一个安全插入方法:
protected function clean_for_insert($data, $skip_empty = ['','0',null]) {
return array_filter($data, function($v) use ($skip_empty) {
return !in_array($v, $skip_empty, true);
});
}
// 使用
$clean_data = $this->clean_for_insert($_POST);
$this->db->insert('users', $clean_data); // 空字段被剔除,DB 默认值生效
注意:array_filter 默认会重排键,如需保留键名,加第三个参数 ARRAY_FILTER_USE_KEY 并改用回调判断键值。
时间字段的特殊处理
比如 created_at 设为 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,就别在 PHP 里赋值。但如果业务需要手动指定时间,又想留空时走默认值,可用:
- 前端提交时,时间字段留空不传(
$_POST中无该 key) - 或后端判断:
if (isset($_POST['created_at']) && $_POST['created_at']) { $this->db->set(...); } - 避免用
date('Y-m-d H:i:s')赋默认值——这会覆盖数据库的CURRENT_TIMESTAMP











