Yii ActiveRecord 和缓存中的 beforeFind()

beforeFind() in Yii ActiveRecord and cache

在某些模型中 classes 我想实现缓存。我想这样做:

UsersModel::model()->findByAttributes([...])

在那个 class 中,我想覆盖方法 beforeFind() 以首先将请求发送到缓存服务器,但似乎该方法不采用任何其他参数,也没有具有属性的对象。

在顶层代码中添加额外的 conditions/checks,例如:

$response = Yii::app()->cache->get('userUserLogin');
if(empty($response) == true) {
    //fetch data from db and set to cache
    $userModel = UsersModel::model->findByAttributes([...])
    Yii::app()->cache->set('user' . $userModel->username, $userModel->getAttributes());
}

不好看又琐碎,导致很多分支。

你不应该为此使用 beforeFind()。除了实施中的技术问题外,您可能会因此而产生许多副作用并且难以调试错误。这是因为缓存可能已过时,许多内部 Yii 逻辑可能依赖于假设,即 findByAttributes()(和其他方法)总是从数据库中获取新数据。您也将无法忽略缓存并直接从数据库中获取模型。


一般来说,您有 2 个选择:

1。使用 CActiveRecord::cache()

$model = UsersModel::model()->cache(60)->findByAttributes([...])

这将查询缓存结果 60 秒。

2。自定义助手

您可以添加自定义方法,这将简化缓存活动记录的使用:

public static function findByAttributesFromCache($attributes = []) {
    $result = Yii::app()->cache->get(json_encode($attributes));
    if ($result === false) {
        //fetch data from db and set to cache
        $result = static::model()->findByAttributes($attributes);
        Yii::app()->cache->set(json_encode($attributes), $result, 60);
    }

    return $result;
}

您可以将此类方法添加到特征中,并在多个模型中重复使用。那么你只需要:

$userModel = UsersModel::findByAttributesFromCache([...]);