插件窝 干货文章 ThinkPHP模型setInc/setDec方法为何无法自动更新时间戳?

ThinkPHP模型setInc/setDec方法为何无法自动更新时间戳?

方法 更新 时间 自动 987    来源:    2025-03-13

在ThinkPHP框架中,setIncsetDec 方法用于对数据库中的某个字段进行自增或自减操作。然而,这些方法默认不会自动更新模型的 update_time 时间戳字段。这是因为 setIncsetDec 是直接对数据库进行操作,而不是通过模型的 save 方法来更新数据。

原因分析

  1. 直接操作数据库setIncsetDec 方法是直接通过SQL语句对数据库进行更新操作,绕过了模型的 save 方法,因此不会触发模型的自动时间戳更新机制。

  2. 自动时间戳机制:ThinkPHP 的自动时间戳更新机制是通过模型的 save 方法触发的。当调用 save 方法时,框架会自动检查模型是否启用了自动时间戳,并在更新数据时自动更新 update_time 字段。

解决方案

如果你希望在调用 setIncsetDec 方法时自动更新时间戳,可以通过以下几种方式实现:

1. 手动更新时间戳

在调用 setIncsetDec 方法后,手动调用 save 方法来更新时间戳。

$model = Model::find($id);
$model->setInc('field_name');
$model->save();

2. 使用 update 方法

你可以使用 update 方法来同时更新字段和时间戳。

$model = Model::find($id);
$model->update([
    'field_name' => $model->field_name + 1,
    'update_time' => time(),
]);

3. 使用 Db 类直接操作数据库

如果你不想通过模型操作,可以直接使用 Db 类来执行SQL语句,并手动更新时间戳。

Db::name('table_name')
    ->where('id', $id)
    ->inc('field_name')
    ->update(['update_time' => time()]);

4. 扩展 setIncsetDec 方法

你可以在模型中扩展 setIncsetDec 方法,使其在调用时自动更新时间戳。

class MyModel extends Model
{
    public function setIncWithTimestamp($field, $step = 1)
    {
        $this->setInc($field, $step);
        $this->save();
    }

    public function setDecWithTimestamp($field, $step = 1)
    {
        $this->setDec($field, $step);
        $this->save();
    }
}

然后你可以这样调用:

$model = new MyModel();
$model->setIncWithTimestamp('field_name');

总结

setIncsetDec 方法默认不会自动更新时间戳,因为它们直接操作数据库而不经过模型的 save 方法。你可以通过手动调用 save 方法、使用 update 方法、直接使用 Db 类或扩展模型方法来实现自动更新时间戳的功能。