在Yii ActiveRecord中,是否可以在模型构造函数中设置属性并且仍然保持模型的isNewRecord属性为true?
我有一个模型构造函数来创建一个私有属性来保存PHPPass密码哈希实例。当我这样做时,它将isNewRecord属性设置为false,即使该记录是新建的。
如果id属性大于零,我尝试在构造函数中调用setIsNewRecord(true),但似乎构造函数中没有属性。
我必须删除构造函数,并在每个需要phpass的方法中生成语句。
用户模型的构造函数:
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
}
答案 0 :(得分:5)
当ovveriding contstructor 确保调用父构造函数时。在ovveriding时总是调用父构造函数,除非你知道你在做什么。
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提供有关ovverding构造函数的question链接。
要添加的另一个重要注释:请记住将参数传递给构造函数。在Yii模型类中,$scenario
参数具有默认值insert
。当你在没有传递这个参数的情况下使用构造函数时,将始终存在insert
场景,并且不会有任何关于缺失参数的错误消息,因为它具有默认值。我使用$scenario
更新了代码。
答案 1 :(得分:3)
通常,您应该避免覆盖Yii类中的构造函数。大多数组件都提供init()
方法,而不像您的示例中那样适用于代码。
不同之处在于,应用程序组件对象已经应用了所有配置。这与您的案例无关,但使用init()
代替__construct()
仍是一种好习惯。