

新闻资讯
技术学院MySQL 的 DEFAULT 约束在数据库层面生效,INSERT 时省略字段才触发默认值;PHP 不自动填充,传 NULL 会绕过 DEFAULT;DATETIME 与 TIMESTAMP 默认行为不同,需注意严格模式一致性。
DEFAULT 设置字段默认值PHP 本身不提供“新增数据时自动填默认值”的机制,真正起作用的是数据库层面的 DEFAULT 约束。只要你在建表或修改表时为字段指定了 DEFAULT,INSERT 语句中省略该字段,MySQL 就会自动填入默认值。
常见错误是只在 PHP 数组里设个 $data['status'],但没在数据库加约束——这样一旦绕过 PHP(比如直接 SQL 插入、CLI 脚本、其他语言调用),默认逻辑就失效了。
= 'active'
DEFAULT 值必须是常量:比如 'pending'、0、CURRENT_TIMESTAMP;不能是函数调用如 NOW()(MySQL 5.6.5+ 允许 CURRENT_TIMESTAMP,但 NOW() 仍非法)NOT NULL 字段设 DEFAULT 很关键,否则 INSERT 时漏掉它会报错 Field 'xxx' doesn't have a default value
ALTER TABLE users ADD COLUMN role VARCHAR(20) DEFAULT 'user';或修改已有字段:
ALTER TABLE users ALTER COLUMN status SET DEFAULT 'draft';
NULL 会绕过 DEFAULT
很多人以为只要字段有 DEFAULT,INSERT 时传 NULL 也会触发默认值,其实不会。MySQL 把 NULL 当作一个明确值来处理,哪怕字段允许 NULL,也不会回退到 DEFAULT。
例如字段定义为 level TINYINT DEFAULT 1:
INSERT INTO users (name) VALUES ('Alice'); → level 自动为 1
INSERT INTO users (name, level) VALUES ('Bob', NULL); → level 存的是 NULL,不是 1
null 或空字符串array_merge() 补默认值当业务逻辑复杂、字段默认值可能随条件变化(比如不同用户角色初始权限不同),或者你无法修改数据库结构时,可以在 PHP 插入前统一补值。
注意别用 array_merge(['status' => 'draft'], $input) —— 这会强制覆盖 $input 里的同名键。正确做法是只补缺失的键:
$defaults = ['status' => 'draft', 'created_at' => date('Y-m-d H:i:s')];
$data = array_merge($defaults, array_filter($input, function($v) { return $v !== null && $v !== ''; }));
更稳妥的方式是白名单过滤 + 显式赋值:
$allowed = ['name', 'email', 'status', 'role'];
$data = [];
foreach ($allowed as $field) {
$data[$field] = $input[$field] ?? ($defaults[$field] ?? null);
}
datetime 和 timestamp 字段的默认行为差异这两个类型设 DEFAULT CURRENT_TIMESTAMP 表现不同,容易踩坑:
TIMESTAMP 字段支持 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,一条语句搞定创建和更新时间DATETIME 在 MySQL 5.6.5+ 才支持 CURRENT_TIMESTAMP 作为默认值,且不支持 ON UPDATE(除非用触发器)date('Y-m-d H:i:s') 生成时间再插入,会丢失时区上下文;不如交给数据库用 CURRENT_TIMESTAMP 更可靠DATETIME 且没设默认值,又没在 PHP 中传值,MySQL 5.7+ 严格模式下会报错 Invalid default value for 'created_at'
DEFAULT 不生效或报错不一致**。上线前务必确认 sql_mode 配置统一。