thinkphp5模型时间戳需显式设置$autowritetimestamp为true或字符串类型,否则不触发;db类操作不支持自动时间戳,仅模型方法生效;字段名、格式、数据库类型、调用方式四者必须严格匹配。

$autoWriteTimestamp 必须显式设为 true 或字符串类型(如 'datetime'),否则模型层的时间戳自动写入根本不会触发——全局配置 'auto_timestamp' => true 只是“允许”,不是“启用”。
为什么 save() 不写入 create_time 字段
最常见原因是模型里漏写了 $autoWriteTimestamp = true;。ThinkPHP5 默认关闭模型级时间戳,全局配置不等于模型生效。
- 必须在模型类中声明
protected $autoWriteTimestamp = true;(或'datetime'、'timestamp') - 若数据库字段名不是
create_time/update_time,还得同步配protected $createTime = 'created_at';和protected $updateTime = 'updated_at'; - 字段名必须和数据库列名**完全一致**:大小写、下划线、前缀都不能错,比如
add_time写成addTime就静默失效 - 如果只想要更新时间,创建时间字段又不存在,把
$createTime设为false,别留空或null
Db::insert() 为什么永远不写时间戳
Db::table('user')->insert($data) 绕过了模型生命周期,beforeWrite 钩子、时间戳逻辑、类型转换全都不走——这是设计使然,不是 bug。
- 自动时间戳只在模型方法中生效:
$model->save()、$model->create()、$model->update() - 用
Db类操作时,时间字段得手动赋值:$data['create_time'] = date('Y-m-d H:i:s'); - 批量导入等场景若想保留自动机制,建议用
$model->saveAll($list),它会逐条走模型流程
写进去了但显示 0000-00-00 00:00:00
这是格式与字段类型错配的典型表现:写入格式是字符串,但数据库字段是 INT;或反过来,写入整数却塞进了 DATETIME 字段。
- 设
$autoWriteTimestamp = 'datetime'→ 数据库字段必须是DATETIME或TIMESTAMP - 设
$autoWriteTimestamp = 'timestamp'→ 字段建议用INT(11)或BIGINT -
true值依赖全局配置'auto_timestamp',容易被忽略,建议直接写死字符串类型 - 查错时调用
$model->getLastSql()看生成的 SQL,比猜配置更可靠
allowField(true) 导致时间戳字段被丢弃
当开启白名单模式时,save() 只会写入你明确列出的字段,时间戳字段不在列表里就直接被过滤掉,连 warning 都没有。
- 避免在
save()中传field参数,除非你主动把时间字段加进去:$model->save($data, [], ['create_time', 'update_time']) - 若用
allowField(true),务必确认白名单数组包含对应时间字段名,且拼写完全一致 - 更稳妥的做法是:不用白名单,改用
protected $readonly = ['id'];控制不可写字段
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











