【问题标题】:How can I update only certain fields in a Yii framework?如何只更新 Yii 框架中的某些字段?
【发布时间】:2012-11-23 10:42:05
【问题描述】:

我不想更新密码字段。如何使用它。我使用 md5 编码作为密码。所以我不想更新 yii 框架中的密码字段。有什么帮助吗??

【问题讨论】:

    标签: php yii


    【解决方案1】:

    我认为更好的方法是在这种情况下不使用该场景。规则中的下一个代码只是对场景说:下一个字段是必需的。但不是:跳过其他其他

    array('name, username, email', 'required', 'on' => 'update'),
    

    例如,如果我们将密码的长度限制为最多 32 个字符,但是在数据库中以 sha1 格式存储(长度为 40),那么我们就会遇到问题,因为验证器会阻塞数据库查询。这是因为当您进行更新时,“验证”方法会检查所有类属性(关于数据库表映射),而不仅仅是邮寄的新属性。

    可以使用方法“saveAttributes”,但后来我注意到另一个问题。如果“email”列在数据库中是唯一的,并且如果编辑的电子邮件与现有的电子邮件重复,则规则中定义的 Yii 消息系统无法通知并抛出有关数据库查询的错误代码。

    我认为最简单的方法是:在这种情况下不要设置场景。只需将您想要的属性作为参数发送。这将保留 GII 创建的所有 CRUD 功能。

    在您的代码中,它看起来像这样: (模型中)

    public function rules() {
        return array(
            array('name, username, email, password', 'required'),
        );
    }
    

    (在控制器中)

    if($id==Yii::app()->user->id){ 
        $model=$this->loadModel($id); 
        if(isset($_POST['JbJsJobResume'])) { 
            $model->attributes=$_POST['JbJsJobResume']; 
            if($model->save(true, array('name', 'username', 'email'))) 
                $this->redirect(array('view','id'=>$model->id)); 
        } 
    
        $this->render('update',array( 'model'=>$model, )); 
    }
    

    我注意到您不使用 RBAC。非常方便灵活 - 试试吧。

    http://www.yiiframework.com/doc/guide/1.1/en/topics.auth#role-based-access-control

    【讨论】:

    • 请注意,saveAttributes() 不会对正在保存的数据进行验证。
    • 像魅力 +1 一样为我工作 :)
    【解决方案2】:

    在您的模型中,您必须执行以下操作:

    public function rules() {
        return array(
            array('name, username, email, password', 'required', 'on' => 'create'),
            array('name, username, email', 'required', 'on' => 'update'),
        );
    }
    

    假设您现在运行的场景是更新。所以我不需要那里的密码。我仅在您可能拥有的创建场景中需要它。因此,在您拥有的视图文件中删除密码字段并在您拥有的操作中包含以下内容:

    $model->setScenario('update');
    

    所以它不需要密码并且会保持不变。

    对于密码更改,您可以创建一个新操作(例如 actionPassChange),您需要输入两次新密码。

    【讨论】:

    • 如果您遵循方案选项,那么对于您现在运行的操作,您必须在加载 $model 后立即设置方案。通过从视图中删除密码字段,验证将不需要此属性。请说明您的错误,以便更好地了解您的问题。
    • 你能简单解释一下吗??
    • 如果您在使用的操作中设置控制器内的场景,则只需三个字段即可保存模型。你不明白什么?运行你的脚本,如果有错误给我们错误信息。
    • 是的,我不明白。我是 yii 的新手 if($id==Yii::app()->user->id){ $model=$this->loadModel($id); if(isset($_POST['JbJsJobResume'])) { $model->attributes=$_POST['JbJsJobResume']; if($model->save()) $this->redirect(array('view','id'=>$model->id)); $this->render('update',array('model'=>$model, ));现在在控制器中。如何添加场景??
    • 在这里结帐yiiframework.com/wiki/266/understanding-scenarios & yiiframework.com/forum/index.php/topic/… 我希望这将通过示例进一步帮助您
    【解决方案3】:
    $model->attributes=$_POST['JbJsJobResume'];
    

    而不是分配所有属性只分配那些你想保存的, 作为

    $model->name=$_POST['JbJsJobResume']['name'];
    $model->save();
    

    【讨论】:

    • $model->name=$_POST['JbJsJobResume']['name']; ['name'] 是 db 字段名还是表单字段名?
    • $model->name 这里name是表列名$_POST['JbJsJobResume']['name'];是表单数据。 print_r($_POST) 并找出数据在哪个 post 变量中。
    【解决方案4】:

    第一个选项只需在设置密码字段之前取消设置:

    function update(){
        $model=$this->loadModel($id);
        unset($_POST['JbJsJobResume']['password']);
        $model->attributes=$_POST['JbJsJobResume'];
        $model->save();  
    }
    

    第二个选项:使用临时变量:

    function update(){
        $model=$this->loadModel($id);
        $temPassword = $model->passwrod;
        $model->attributes=$_POST['JbJsJobResume'];
        $model->passwrod = $temPassword;
        $model->save();  
    }
    

    第三个选项:使用scenarios

    【讨论】:

      【解决方案5】:

      我不确定为什么会出现这个问题,一些代码可以帮助我们理解原因。如果您不希望捕获/更新密码,那为什么表单中有密码字段?

      如果您从视图中删除密码字段,密码字段的值将不会被发送回控制器,因此也不会更新。

      上述方法有可能不起作用,这可能是在您的用户模型中,您正在使用afterValidate 方法加密密码?:

      protected function afterValidate()
      {
          parent::afterValidate();
          $this->password = $this->encrypt($this->password);
      }
      
      public function encrypt($value)
      {
          return md5($value);
      }
      

      在这种情况下,如果您从视图中删除密码字段,而只是更新姓名、用户名或电子邮件,那么密码的 md5 哈希将自动重新哈希,您将丢失真实密码。

      解决此问题的一种方法是在 afterValidate 方法(创建或更新)中 md5 密码,但是如果用户希望以相同的形式更改个人资料详细信息,请要求用户再次验证他们的密码。

      1. FORM:用户更改名称并验证密码
      2. 已发布表格
      3. 控制器调用验证方法。
      4. 如果验证为真,覆盖用户表中的条目(包括验证密码)

      【讨论】:

        【解决方案6】:

        我认为@Gravy 的回答是正确的,谢谢 Gravy 和 Nikos Tsirakis。我已经修复了与@faizphp 几乎相同的问题。正如 Nikos Tsirakis 所说,我为用户模型添加了场景,但也遇到了同样的问题。然后我发现我在User.afterValidate中加密了密码,所以每次更新用户模型时,程序再次将数据库中的密码加密为错误的密码。所以我改变了我的功能

        protected function afterValidate()
        {
                parent::afterValidate();
                if (!$this->hasErrors())
                    $this->password = $this->hashPassword($this->password);
        }
        </code>
        



        protected function afterValidate()
        {
                parent::afterValidate();
                if (!$this->hasErrors() && $this->scenario==="create")
                    $this->password = $this->hashPassword($this->password);
        }
        

        。 这似乎工作。

        【讨论】:

          猜你喜欢
          • 2020-08-17
          • 1970-01-01
          • 1970-01-01
          • 2014-08-09
          • 2010-12-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多