thinkphp模型default仅对null或未设置字段生效,空字符串、0等假值会绕过;需用autowrite配合type控制时机,并确保default类型与数据库字段匹配。

ThinkPHP 模型字段没传值时,default 不生效?
不是 default 写错了,而是 ThinkPHP 的模型默认值只在「新增」且字段为 NULL 或完全未设置时才触发;如果前端传了空字符串、0、false 甚至空数组,default 就被绕过去了。
常见错误现象:create_time 设了 default => 'datetime',但 POST 提交带了个 create_time=(空字符串),结果数据库存了 '' 而不是当前时间。
- 必须用
autoWrite+type配合default,比如['datetime', 'create_time' => ['default' => 'datetime']] -
default值只对NULL和未赋值字段起作用,对''、0、[]等“假值”无效 - 若字段允许为空(
nullable),且你希望空字符串也走默认逻辑,得手动过滤:在save()前用$data = array_filter($data, function($v) { return $v !== ''; });
用 auto 和 autoWrite 区分「新增」和「更新」场景
ThinkPHP 的 auto(旧版)和 autoWrite(新版)控制字段自动写入时机,但很多人混淆了它们的触发条件:前者是模型属性级配置,后者是数据写入级钩子。
典型误用:把 update_time 放进 default,结果新增和更新都不更新——它根本不是用来做「更新时自动写」的。
-
autoWrite中设['update_time' => ['datetime', 'update']],表示仅在更新操作中写入当前时间 -
['create_time' => ['datetime', 'insert']]表示只在新增时写入 - 如果字段同时需要 insert/update 都生效(如状态字段),得拆成两条规则,或改用事件回调
beforeWrite - 注意:使用
save()时需显式传$data,否则autoWrite可能因无变化字段而跳过
字段类型不匹配导致 default 被忽略
MySQL 字段定义是 DATETIME,但模型里写了 default => time()(整数时间戳),TP 会尝试强制转换失败后静默丢弃该字段,默认值就没了。
错误信息不会报出,只会存 NULL 或数据库默认(如 0000-00-00 00:00:00),排查时容易以为是逻辑问题。
- 查清数据库字段类型:
DATETIME对应'datetime',TIMESTAMP对应'timestamp',INT对应'int' -
default值必须与字段类型兼容:日期类字段别直接写time(),改用'datetime'字符串类型自动处理 - 自定义函数默认值(如
default => function() { return md5(uniqid()); })只在新增时执行一次,不是每次 save 都调
批量写入(saveAll)下 default 和 autoWrite 行为异常
saveAll 默认关闭所有自动写入逻辑,哪怕模型里配了 autoWrite,也不会触发。这是为了性能妥协,但新手常踩坑。
现象:单条 save() 正常填充 create_time,换成 saveAll($list) 后全变成 NULL。
- 必须显式开启:
UserModel::saveAll($list, ['auto' => true]) - 注意:开启后,每条数据都会独立执行
autoWrite规则,但不会重新校验主键是否存在(即不会自动区分 insert/update) - 如果数据含主键且想混合更新/插入,建议改用
replace()或分批save() - 大批量场景慎用
auto,避免重复调用时间函数或 UUID 生成器影响性能
default。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










