Thinkphp5.1 save循环更新同一张表的bug($this->origin)

8 篇文章 0 订阅
2 篇文章 0 订阅

问题简述:
批量更新同一张表数据的状态,只有一条更新成功

使用的model更新语句是:

$pk = $this->pk;
$this->isUpdate(true)->save(array_merge($data, [$pk => $id])) 

控制器:

$teacherAuditL = new TeacherAuditLogic();
$teacherAuditL->infoAudit($sId, $data['audit'], $data['reason']);

中间件:

public function infoAudit($id, $accept, $reason = '') {
	$teacherInfoAuditFlowM = new TeacherInfoAuditFlow();
	Db::startTrans();
	try {
		$aId = explode(',',$id);
		foreach($aId as $v){
		    $teacherInfoAuditFlowM->improve($v, ['status' => 'yes' == $accept ? TeacherInfoAuditFlowEnum::STATUS_SUCCESS : TeacherInfoAuditFlowEnum::STATUS_FAIL, 'reason' => $reason]);
		}
	} catch (\Throwable $e) {
	    Db::rollback();
	    throw new ApplicationException(['msg' => $e->getMessage()]);
	}
}

结果只有第一条传入的数据变更了,后续的id并没有更新
经过排查,发现Model.php文件中的方法save中 $this->origin = $this->data;

public function save($data = [], $where = [], $sequence = null) {
        if (is_string($data)) {
            $sequence = $data;
            $data = [];
        }
        if (!$this->checkBeforeSave($data, $where)) {
            return false;
        }
        $result = $this->exists ? $this->updateData($where) : $this->insertData($sequence);
        if (false === $result) {
            return false;
        }
        // 写入回调
        $this->trigger('after_write');
        // 重新记录原始数据
        $this->origin = $this->data;
        $this->set = [];
        return true;
    }

导致第一个id的更新数据被记录,后续的id要更新的内容经过比对后又一致,结果就只有id要被更新
Attribute.php,经过这个方法处理后,就没有数据要更新了

/**
     * 获取变化的数据 并排除只读数据
     * @access public
     * @return array
     */
    public function getChangedData() {
        if ($this->force) {
            $data = $this->data;
        } else {
            $data = array_udiff_assoc($this->data, $this->origin, function ($a, $b) {
                dump(['a'=>$a,'b'=>$b]);
                if ((empty($a) || empty($b)) && $a !== $b) {
                    return 1;
                }

                return is_object($a) || $a != $b ? 1 : 0;
            });
        }
        if (!empty($this->readonly)) {
            // 只读字段不允许更新
            foreach ($this->readonly as $key => $field) {
                if (isset($data[$field])) {
                    unset($data[$field]);
                }
            }
        }
        return $data;
    }

解决办法:

1.注释掉Model.php 的 $this->origin = $this->data; 这行代码
2.把循环在controller层实现,目的是把初始化model包在循环里

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值