ThinkPHP 8.0 批量插入不自动写入时间戳——因 Model::insertAll() 和 Db::table()->insertAll() 绕过模型层;需手动赋值 create_time/update_time 或配合 $type 配置使用 'now'(仅 datetime 有效),Pivot 表及 Db 类操作均不支持自动时间戳。

ThinkPHP 8.0 中批量添加数据时,自动写入时间戳默认不生效——这是关键前提。框架只在单条模型实例创建(如 $model->save() 或 Model::create())时触发时间戳逻辑;而 Model::insertAll()、Db::table()->insertAll() 等批量操作绕过模型层,不会自动填充 create_time、update_time 等字段。
确认模型已启用时间戳功能
确保模型类中正确开启并配置了自动时间戳:
- 设置
$autoWriteTimestamp = true(或'datetime'/'int'指定类型) - 声明时间字段名,例如:
protected $createTime = 'create_time'; protected $updateTime = 'update_time'; - 切勿把
deleted_at加进$createTime或$updateTime,否则新增记录会被误判为已软删除
批量插入时手动补全时间戳字段
最直接可靠的方式:在数据数组中显式赋值时间字段,不依赖模型自动处理:
- 若数据库字段是 datetime 类型:
$data = ['name' => '张三', 'create_time' => date('Y-m-d H:i:s')]; - 若字段是 int 类型(Unix 时间戳):
'create_time' => time() - 批量插入时统一处理:
$list = array_map(fn($item) => array_merge($item, ['create_time' => time()]), $rawList);
用模型 insertAll 并配合 type 显式转换
若坚持使用模型的 insertAll() 方法,需配合 $type 配置 + 手动传入时间值,才能让类型转换生效:
立即学习“PHP免费学习笔记(深入)”;
- 在模型中定义:
protected $type = ['create_time' => 'datetime', 'update_time' => 'datetime']; - 插入时仍需提供时间值:
User::insertAll([['name' => '李四', 'create_time' => 'now']]);// 'now' 会被 $type 转成当前时间 - 注意:
'now'是 TP 内置识别字,仅对datetime类型有效;int类型需传time()或时间戳整数
避免踩坑的硬性提醒
- Pivot 关联中间表模型 不支持自动时间戳,即使配置了也会静默失败,created_at 字段将为空或 0
- 使用
Db::table()->insertAll()完全不走模型层,$autoWriteTimestamp和$type均无效,必须手动生成时间字段 - 严格模式(
declare(strict_types=1))下,若时间字段类型与数据库不匹配(如数据库是 int 却传字符串),可能存入 0 而非报错



















