繁体   English   中英

如何只更新Yii框架中的某些字段?

[英]How can I update only certain fields in a Yii framework?

在此处输入图片说明

我不想更新密码字段。如何使用它。我使用md5编码作为密码。所以我不想在yii框架中更新密码字段。任何帮助表示赞赏?

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

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

例如,如果我们将密码的长度限制为最多32个字符,但是在数据库中以sha1(长度为40)的格式存储密码,则由于验证器将阻止数据库查询,因此会出现问题,这是因为当您进行更新后,“validatе”方法将检查所有类属性(有关数据库表映射),而不仅仅是检查通过邮递交付的新属性。

可以使用方法“ saveAttributes”,但是随后我注意到了另一个问题。 如果“电子邮件”列在数据库中是唯一的,并且如果编辑过的电子邮件重复了现有邮件之一,则规则中定义的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

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

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->attributes=$_POST['JbJsJobResume'];

而不是分配所有属性,只需分配仅要保存的属性即可

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

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

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();  
}

第三种选择:使用方案

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

如果从视图中删除密码字段,则密码字段的值将不会回传到控制器,也不会更新。

上面的方法可能不起作用,可能是在您的User模型中,您正在使用afterValidate方法对密码进行加密?:

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

public function encrypt($value)
{
    return md5($value);
}

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

解决此问题的一种方法是在afterValidate方法(创建或更新)中对密码进行md5加密,但是如果用户希望以相同的形式更改配置文件详细信息,请要求用户再次验证其密码。

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

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

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);
}

看来行得通。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM