由于构造函数,Yii模型isNewRecord为false

时间:2013-05-02 17:51:17

标签: php mysql activerecord yii

在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
}

2 个答案:

答案 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()仍是一种好习惯。