这个应该是和项目框架有关,项目中数据库 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值为null2,在删除操作时,会报错,说格式不符合,因为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并未自动更新
