最近使用tp5框架模型更新数据时出现了一点小问题:
foreach($user as $k => $v) {
if(某些条件满足) {
$this->save(['score'=>$v['score']],['id'=>$v['id']]);
}
}
当更新的数据一样,即使条件不一致时,save方法也不会更新数据。
解决方法:
加上isUpdate(true)更新数据。
$this->isUpdate(true)->save(['score'=>$v['score']],['id'=>$v['id']]);
tp5 update方法源码中也是使用这种方式
/**
* 更新数据
* @access public
* @param array $data 数据数组
* @param array $where 更新条件
* @param array|true $field 允许字段
* @return $this
*/
public static function update($data = [], $where = [], $field = null)
{
$model = new static();
if (!empty($field)) {
$model->allowField($field);
}
$result = $model->isUpdate(true)->save($data, $where);
return $model;
}
补充一下官方文档:
模型的新增和更新方法都是 save 方法,系统有一套默认的规则来识别当前的数据需要更新还是新增。
- 实例化模型后调用save方法表示新增;
- 查询数据后调用save方法表示更新;
- save方法传入更新条件后表示更新;
如果你的数据操作比较复杂,可以显式的指定当前调用 save 方法是新增操作还是更新操作。
显式更新数据:
// 实例化模型
$user = new User;
// 显式指定更新数据操作
$user->isUpdate(true)
->save(['id' => 1, 'name' => 'thinkphp']);
显式新增数据:
$user = User::get(1);
$user->name = 'thinkphp';
// 显式指定当前操作为新增操作
$user->isUpdate(false)->save();
注意:
- 不要在一个模型实例里面做多次更新,会导致部分重复数据不再更新,正确的方式应该是先查询后更
新或者使用模型类的 update 方法更新。 - 如果你调用save方法进行多次数据写入的时候,需要注意,第二次save方法的时候必须使用
isUpdate(false),否则会视为更新数据。