thinkphp5模型需显式启用自动时间戳:设protected $autowritetimestamp = true,默认字段为create_time和update_time;自定义字段名需配置$createtime和$updatetime;save()更新时须确保主键存在或调用isupdate(true),否则不触发update_time写入。

ThinkPHP5 的模型时间戳默认不自动写入,必须显式开启并配置字段名,否则 create_time 和 update_time 不会自动填充。
如何在模型中启用自动时间戳
ThinkPHP5 默认关闭自动时间戳,需在模型类中设置 protected $autoWriteTimestamp = true;。该配置仅控制“是否启用”,不指定字段名或格式。
- 若设为
true,框架会默认使用create_time和update_time两个字段 - 若设为
'datetime'或'timestamp',会同时控制写入值的类型(字符串 or 整型) - 不写这行配置,或设为
false,哪怕字段存在也不会自动写入
如何自定义时间戳字段名
当数据库字段不是 create_time/update_time 时(比如叫 add_time、last_modify),必须用 protected $createTime 和 protected $updateTime 显式声明。
-
protected $createTime = 'add_time';—— 新增时写入add_time -
protected $updateTime = 'last_modify';—— 更新时写入last_modify - 若只需自动写入创建时间,可只设
$createTime,并把$updateTime设为false - 字段名区分大小写,且不能带表前缀
为什么 save() 不触发 update_time?
这是最常踩的坑:save() 方法默认按主键更新,但不会自动识别“这是更新操作”,除非明确传入主键值或调用 isUpdate(true)。
- 新增数据:用
create()或save()+ 主键为空 → 自动写create_time和update_time - 更新数据:必须确保主键有值,且推荐用
save(['id' => 123, 'name' => 'xxx'])或save($data, ['id' => 123]) - 更稳妥的方式是显式调用
$model->isUpdate(true)->save($data),强制走更新逻辑 - 直接
Db::name('user')->where(...)->update(...)绕过模型,时间戳完全不会生效
时间戳类型选 datetime 还是 timestamp?
选哪种取决于字段类型和业务需求,不是随便配的。
- 数据库字段是
DATETIME或DATE类型 → 配$autoWriteTimestamp = 'datetime',写入如'2024-05-20 14:30:00' - 字段是
INT(长度10)→ 配$autoWriteTimestamp = true或'timestamp',写入秒级时间戳如1716215400 - 配错会导致写入失败(如 datetime 字段里塞了整数)或查询异常(如 where time > 1716215400 在 datetime 字段上无意义)
- 注意 MySQL 5.6+ 的
TIMESTAMP字段有自动更新行为,与 TP 的自动写入可能冲突,建议统一用DATETIME+'datetime'配置
真正容易被忽略的是:时间戳行为高度依赖模型实例的“操作上下文”——新增/更新判断靠主键是否存在,而主键是否被识别又受 pk 属性、数据键名、是否调用 isUpdate() 影响。没跑通的时候,先 dump 一下当前模型的 $model->getData() 和 $model->getChangedData(),比查文档更快定位问题。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











