3

在 Yii ActiveRecord 中,是否可以在模型构造函数中设置一个属性,并且模型的 isNewRecord 属性仍然为真?

我有一个模型构造函数来创建一个私有属性来保存一个 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']);
}

控制器中的用户模型初始化和 isNewRecord 条件

public function actionEdit($id = null)
{

    $myModel = new User();       
    echo $myModel->isNewRecord;   //false due to constructor
}
4

2 回答 2

5

当 ovveriding 构造函数时,确保调用父构造函数。在 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 提供有关过度构造函数的问题的链接。

要添加的另一重要注意事项:记住将参数传递给构造函数。在 Yii 模型类中有$scenario默认值的参数insert。当你在没有传递这个参数的情况下 ovveride 构造函数时,总会有insert场景,并且不会有任何关于缺少参数的错误消息,因为它具有默认值。我用$scenario.

于 2013-05-02T20:23:40.220 回答
3

一般来说,你应该避免覆盖 Yii 类中的构造函数。大多数组件都提供了一种init()方法,它是您示例中代码的正确位置。

不同之处在于,对于应用程序组件,对象已经应用了所有配置。这与您的情况无关,但使用init()而不是__construct().

于 2013-05-03T05:14:59.977 回答