这个应该是和项目框架有关,项目中数据库 update_time
和 create_time
数据类型是datetime
格式,而delete_time
数据类型是timestamp
格式。
// 自动写入时间戳字段
// true为自动识别类型 false关闭
// 字符串则明确指定时间字段类型 支持 int timestamp datetime date
'auto_timestamp' => false,
// 时间字段取出后的默认时间格式
'datetime_format' => 'Y-m-d H:i:s',
为了达到update_time
和create_time
及delete_time
的同步更新问题,在BaseModel.php
中加入如下代码
abstract class BaseModel extends Model
{
use Lang, SoftDelete;
protected $defaultSoftDelete = 0;
protected static function onBeforeWrite(Model $model)
{
$model[$model->getPk()] or $model->setAttr('create_time', datetime());
$model->setAttr('update_time', datetime());
}
//以下省略若干
}
这个设定上没什么问题。但是,当我在更新一些值时,使用模型更新方法,又不想去变更update_time
的情况,->isAutoWriteTimestamp(false)->save()
就会发现根本不起作为。其实这个操作中的判断是vendor\topthink\think-orm\src\Model.php
这个文件中的updateData()
方法
/**
* 保存写入数据
* @access protected
* @return bool
*/
protected function updateData(): bool
{
// 事件回调
if (false === $this->trigger('BeforeUpdate')) {
return false;
}
//这儿省略一坨...
if ($this->autoWriteTimestamp && $this->updateTime) {
// 自动写入更新时间
$data[$this->updateTime] = $this->autoWriteTimestamp();
$this->data[$this->updateTime] = $this->getTimestampValue($data[$this->updateTime]);
}
//这儿省略一坨...
}
代码中isAutoWriteTimestamp(false)
使得$this->autoWriteTimestamp
值为false
而无法进入 自动写入更新时间 这一判断逻辑中。这个就是tp框架本身的判断,没有问题。
但由于我们这个架构,在公共模型中加了onBeforeWrite()
这个方法中有对update_time
的更新操作,而这个方法又会被事件 BeforeUpdate
来调用,这下使得我们这个框架中的 isAutoWriteTimestamp(false)
无效。
为了解决这个问题,我就想着去还原框架,既然tp框架自己没有问题,为什么还要自作主张呢。于是我就在去掉onBeforeWrite()
的方法,且在config\database.php
中的'auto_timestamp' => 'datetime',
设置。果然这样处理,isAutoWriteTimestamp(false)
这个操作没有一点问题。但又有很多新问题:
1,在新增操作时,
delete_time
值为null
2,在删除操作时,会报错,说格式不符合,因为delete_time
自动时间也是datetime
类型,存储不了。
这样看来,本身就没办法,我们这个框架中,三个时间类型就不一致。而tp本身支持的恰好是一致的那种设定。
又不能改系统的东西,那么只有恢复代码,既然isAutoWriteTimestamp(false)
不起作用,那么就只有放弃,改用如下的写法:
Db::table('ch_comments')->where(['id' => $pid])->inc('count')->update();
$itemModel::update(['comments' => $itemM->comments - 1], ['id' => $m->item_id], ['comments']);
$itemModel::update($upData, ['id' => $item_id], array_keys($upData));
MyModel::where(['id'=>$param['id']])->update($data);
其中第3个写法,这个见我另一篇文章
模型更新时update_time并未自动更新