Yii2的save()方法容易出错的地方

如果save()返回true, 但是数据没有保存成功,则应该是开启了事务且已经回滚

如果save()返回false, 则使用$model->errors查看错误原因

可以设置$model的场景,对具体的场景进行验证; 没有指定场景的验证规则会在所有的场景通用

save()方法有两个参数,第一个参数为是否开启验证,第二个字段为验证的字段,但是会调用beforeBValidate()

源码如下所示:

public function save($runValidation = true, $attributeNames = null)
    {
        if ($this->getIsNewRecord()) {
            return $this->insert($runValidation, $attributeNames);
        } else {
            return $this->update($runValidation, $attributeNames) !== false;
        }
    }
public function update($runValidation = true, $attributeNames = null)
    {
        if ($runValidation && !$this->validate($attributeNames)) {
            return false;
        }
        return $this->updateInternal($attributeNames);
    }
public function validate($attributeNames = null, $clearErrors = true)
    {
        if ($clearErrors) {
            $this->clearErrors();
        }

        if (!$this->beforeValidate()) {
            return false;
        }

        $scenarios = $this->scenarios();
        $scenario = $this->getScenario();
        if (!isset($scenarios[$scenario])) {
            throw new InvalidParamException("Unknown scenario: $scenario");
        }

        if ($attributeNames === null) {
            $attributeNames = $this->activeAttributes();
        }

        foreach ($this->getActiveValidators() as $validator) {
            $validator->validateAttributes($this, $attributeNames);
        }
        $this->afterValidate();

        return !$this->hasErrors();
    }
protected function updateInternal($attributes = null)
    {
        if (!$this->beforeSave(false)) {
            return false;
        }
        $values = $this->getDirtyAttributes($attributes);
        if (empty($values)) {
            $this->afterSave(false, $values);
            return 0;
        }
        $condition = $this->getOldPrimaryKey(true);
        $lock = $this->optimisticLock();
        if ($lock !== null) {
            $values[$lock] = $this->$lock + 1;
            $condition[$lock] = $this->$lock;
        }
        // We do not check the return value of updateAll() because it‘s possible
        // that the UPDATE statement doesn‘t change anything and thus returns 0.
        $rows = static::updateAll($values, $condition);

        if ($lock !== null && !$rows) {
            throw new StaleObjectException(‘The object being updated is outdated.‘);
        }

        if (isset($values[$lock])) {
            $this->$lock = $values[$lock];
        }

        $changedAttributes = [];
        foreach ($values as $name => $value) {
            $changedAttributes[$name] = isset($this->_oldAttributes[$name]) ? $this->_oldAttributes[$name] : null;
            $this->_oldAttributes[$name] = $value;
        }
        $this->afterSave(false, $changedAttributes);

        return $rows;
    }

原文地址:https://www.cnblogs.com/liuzhiqaingxyz/p/9118541.html

时间: 2024-10-13 14:24:43

Yii2的save()方法容易出错的地方的相关文章

yii2 框架的 save() 方法 执行模式条件。

 save() 方法会调用 insert() 和 update() 中的一个, 用哪个取决于当前 AR 对象是不是新对象(在函数内部,他会检查 yii\db\ActiveRecord::isNewRecord 的值). 若 AR 对象是由 new 操作符 初始化出来的,save() 方法会在表里插入一条数据: 如果一个 AR 是由 find() 方法获取来的, 则 save() 会更新表里的对应行记录.

ThinkPHP 更新数据 save方法

ThinkPHP save() 方法 ThinkPHP 中使用 save() 方法来更新数据库,并且也支持连贯操作的使用. 例子: public function update(){ header("Content-Type:text/html; charset=utf-8"); $Dao = M("User"); // 需要更新的数据 $data['email'] = '[email protected]'; // 更新的条件 $condition['userna

PHP容易出错的地方!

本文对PHP编程中易犯错误进行总结,希望新手能够避免! 1:为什么我得不到变量 我在一网页向另一网页POST数据name,为什么输出$name时却得不到任何值? 在PHP4.2以后的版本中register_global默认为off 若想取得从另一页面提交的变量: 方法一:在PHP.ini中找到register_global,并把它设置为on. 方法二:在接收网页最前面放上这个extract($_POST);extract($_GET);(注意extract($_SESSION)前必须要有Sess

使用Storyboard拖线容易出错的地方

使用Storyboard拖线容易出错的地方: 在Storyboard中,选中某个控件,按住ctrl键进行拖线,建立Outlet和Action后,不能手动再去修改自动生成的代码,然后再次进行连线,这样会导致同一控件被重复连线(被连接到多个方法),编译时不会报错,运行时会直接崩溃. 如果想修改自动生成的代码,必须首先取消之前的连接,然后重新拖线,重新连接.

[原创]java WEB学习笔记79:Hibernate学习之路--- 四种对象的状态,session核心方法:save()方法,persist()方法,get() 和 load() 方法,update()方法,saveOrUpdate() 方法,merge() 方法,delete() 方法,evict(),hibernate 调用存储过程,hibernate 与 触发器协同工作

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

load、save方法、spark sql的几种数据源

load.save方法的用法 DataFrame usersDF = sqlContext.read().load("hdfs://spark1:9000/users.parquet");                usersDF.select("name", "favorite_color").write()                .save("hdfs://spark1:9000/namesAndFavColors.pa

myBatis,mapper查询方法参数传递出错

myBatis,mapper查询方法参数传递出错 接口类mapper的方法: public string getData(String str); mapper.xml文件中sql语句: select * from table1 t where t.str=#{str} 这样可能会报错,报错内容是找不到参数str; 把接口类mapper中的方法参数修改一下: public string getData(@Param(value = "str") String str); 就不报错了

[PHP] Cakephp model save方法不支持tinyint类型存储

不知道为什么 懒得看源码 Model 类调用save()方法的时候不会报错,但是数据无法更新 查了发现是数据库字段使用tinyint类型,我们赋值的时候指定的int, 类型不匹配无法写入. 解决方法是将赋值的时候,将值弄成字符再传入. 参考:http://blog.csdn.net/iefreer/article/details/6904235

MongoDB中insert方法、update方法、save方法简单对比

MongoDB中insert方法.update方法.save方法简单对比 1.update方法 该方法用于更新数据,是对文档中的数据进行更新,改变则更新,没改变则不变. 2.insert方法 该方法用于插入数据到文档中,也就是给文档添加新数据. 3.save方法 该方法同样用于插入数据到文档中,功能是类似于insert方法的.与insert方法不同的是, save方法是遍历文档,逐条将数据插入进去的,而insert方法是将整个文档整体插入进去的. 由两个方法的源码可以看出来. save方法的写法