在Yii ActiveRecord中,是否有可能在模型构造器中设置属性,并且仍然有模型的isNewRecord属性保持为真?
我有一个模型构造函数来创建一个私有属性来保存PHPPass密码哈希实例。当我这样做时,它将isNewRecord属性设置为false,即使该记录是新创建的。
我尝试了一个解决方法,如果id属性大于零,则在构造函数中调用setIsNewRecord(true),但似乎在构造函数中属性不可用。
我必须删除构造函数,并在每个需要phpass的方法中编写语句。
User模型的构造函数:
public function __construct(){
$this->phpass=new PasswordHash(Yii::app()->params['phpass']['iteration_count_log2'], Yii::app()->params['phpass']['portable_hashes']);
}
用户模型init和控制器中的isNewRecord条件
public function actionEdit($id = null)
{
$myModel = new User();
echo $myModel->isNewRecord; //false due to constructor
}
重写构造函数时,确保调用父构造函数。重写时总是调用父构造函数,除非你知道自己在做什么。
public function __construct($scenario = 'insert'){
parent::__construct($scenario);
$this->phpass=new PasswordHash(Yii::app()->params['phpass']['iteration_count_log2'], Yii::app()->params['phpass']['portable_hashes']);
}
还可以将phpass作为静态属性存储,您不需要为每个活动记录实例创建一个新的phpass实例。
编辑:感谢@Kevin提供的关于oververding constructor问题的链接。
要添加的另一个重要注意事项:记住向构造函数传递参数。在Yii模型类中,有默认值为insert
的$scenario
参数。当你重写构造函数而不传递这个参数时,总是会有insert
场景,并且不会有任何关于缺失参数的错误消息,因为它有默认值。我用$scenario
更新了代码
一般情况下,您应该避免在Yii类中重写构造函数。大多数组件提供了一个init()
方法,而不是像你的例子中那样的代码。
init()
而不是__construct()
的良好实践。