当我添加或修改用户记录的时候对于处理确认密码我遇到了一些麻烦,所有我想分享一下我是怎么处理的。
场景是使用的基本的那些(系统自带),你需要有一个数据表(user)并且表中有一个密码字段(password),它使用 sha1、md5或其他加密方式加密用户密码。
面是它的工作流程:当创建用户的时候密码需要加密并且保存,但当修改用户记录时如果使用同样的场景我们最终就会把用户加密过的密码再次加密,这不是我们想要的。我们想要的时当修改时 首先清空模型对象中的密码,把它保存到一个临时的变量中,然后检查密码是否在表单中提交,如果提交了意味着用户的密码需要修改,我们就需要对密码(现在它是纯文本未加密)加密,如果没有提交意味着我们不需要修改,我们就把临时变量的值保存到数据库。
现在让我们看一下代码 ,模型:
<?php if ( ! defined('YII_PATH')) exit('No direct script access allowed');
class User extends CActiveRecord
{
// holds the password confirmation word
public $repeat_password;
//will hold the encrypted password for update actions.
public $initialPassword;
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
//password and repeat password
array('password, repeat_password', 'required', 'on'=>'resetPassword, insert'),
array('password, repeat_password', 'length', 'min'=>6, 'max'=>40),
array('password', 'compare', 'compareAttribute'=>'repeat_password'),
);
}
public function beforeSave()
{
// in this case, we will use the old hashed password.
if(empty($this->password) && empty($this->repeat_password) && !empty($this->initialPassword))
$this->password=$this->repeat_password=$this->initialPassword;
return parent::beforeSave();
}
public function afterFind()
{
//reset the password to null because we don't want the hash to be shown.
$this->initialPassword = $this->password;
$this->password = null;
parent::afterFind();
}
public function saveModel($data=array())
{
//because the hashes needs to match
if(!empty($data['password']) && !empty($data['repeat_password']))
{
$data['password'] = Yii::app()->user->hashPassword($data['password']);
$data['repeat_password'] = Yii::app()->user->hashPassword($data['repeat_password']);
}
$this->attributes=$data;
if(!$this->save())
return CHtml::errorSummary($this);
return true;
}
}
当添加用户时,我们使用 "insert" 场景,此时密码是必需的。当我们修改它的时候我们使用 "update" 场景,此时密码是可选的,提交时密码字段可以为空,并且验证也不会失败。我们可以从临时变量恢复加密后的密码。
下面时控制器中的方法是怎么做的:
public function actionCreate()
{
$user=new User('insert');
$this->saveModel($user);
$this->setViewData(compact('user'));
$this->render('create', $this->getViewData());
}
public function actionUpdate($id)
{
$user=$this->loadModel($id);
$user->scenario='update';
$this->saveModel($user);
$this->setViewData(compact('user'));
$this->render('update', $this->getViewData());
}
protected function saveModel(User $user)
{
if(isset($_POST['User']))
{
$this->performAjaxValidation($user);
$msg = $user->saveModel($_POST['User']);
//check $msg here
}
}
下面时视图中表单的代码:
<section>
<?php echo $form->labelEx($user,'password'); ?>
<div>
<?php echo $form->passwordField($user,'password',array('maxlength'=>40)); ?>
<?php echo $form->passwordField($user,'repeat_password',array('maxlength'=>40)); ?>
</div>
<?php echo $form->error($user,'password'); ?>
</section>
希望这些对你有所帮助。
英文原文:http://www.yiiframework.com/wiki/277/model-password-confirmation-field/