В некоторых классах моделей я хочу реализовать кеш. И я хотел сделать это так:
UsersModel::model()->findByAttributes([...])
В этом классе я хотел переопределить метод beforeFind()
для отправки запроса сначала на сервер кеширования, но кажется, что метод не принимает никаких дополнительных параметров и не имеет объекта с атрибутами.
Ввод дополнительных условий / проверок в код верхнего уровня, например:
$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 варианта:
CActiveRecord::cache()
$model = UsersModel::model()->cache(60)->findByAttributes([...])
Это запросит результаты кеширования в течение 60 секунд.
Вы можете добавить собственные методы, которые упростят использование кэшированных активных записей:
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([...]);