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

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

方法 更新 时间 操作 663    来源:    2025-03-15

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

原因分析

  1. 直接操作数据库setIncsetDec 方法是通过直接生成SQL语句来更新数据库字段的,而不是通过模型的 save 方法。因此,它们不会触发模型的自动时间戳更新机制。

  2. 自动时间戳机制:ThinkPHP 的自动时间戳更新机制是通过模型的 save 方法触发的。当使用 save 方法时,框架会自动更新 update_time 字段(如果配置了自动时间戳)。但 setIncsetDec 方法并不调用 save 方法,因此不会触发这一机制。

解决方案

如果你希望在 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 类来执行更新操作,并手动更新时间戳。

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 类或扩展模型方法来解决问题。选择哪种方法取决于你的具体需求和代码结构。