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


Yii model isNewRecord false due to constructor

在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()的良好实践。