Обертка для кэширования данных¶
Из документации:
// try retrieving $data from cache
$data = $cache->get($key);
if ($data === false) {
// $data is not found in cache, calculate it from scratch
// store $data in cache so that it can be retrieved next time
$cache->set($key, $data);
}
// $data is available here
Можно это дело обернуть в функцию и избавить себя от многократного писания переменных $data, $cache, $key. Тем более, если рядом используется кэширование нескольких фрагментов данных. Ниже функция и укороченный пример ее применения.
namespace common\components;
use Yii;
use yii\helpers\Url;
use yii\helpers\Html;
/**
* Main controller
*/
class Controller extends \yii\web\Controller
{
/**
* Data caching
* @param string $cacheId Cache ID
* @param \Closure $query Data to cache
* @param \yii\caching\Dependency $dependency Cache dependency
* @param int $cacheTime Duration in seconds
* @return mixed Output cached model data
*/
protected function cache($cacheId, \Closure $query, \yii\caching\Dependency $dependency = null, $cacheTime = null)
{
$cacheTime = ($cacheTime === null) ? Yii::$app->option->get('cache_time') : $cacheTime;
$data = Yii::$app->cache->get($cacheId);
if ($data === false) {
$data = $query();
Yii::$app->cache->set($cacheId, $data, $cacheTime, $dependency);
}
return $data;
}
}
namespace frontend\controllers;
use Yii;
use yii\helpers\Html;
use yii\caching\DbDependency;
use yii\web\NotFoundHttpException;
use frontend\models\News\News;
/**
* News controller
*/
class NewsController extends \frontend\components\Controller
{
/**
* Show single news item
* @param string $title News url
* @return \yii\web\View
* @throws \yii\web\NotFoundHttpException
*/
public function actionShow($title)
{
$title = Html::encode($title);
$news = $this->cache(
'news_' . Yii::$app->language . '_t' . md5($title),
function() use ($title) {
return News::find()
->with(['newsTranslates' => function($query) {
$query->andWhere(['lang' => Yii::$app->language]);
}])
->show($title)
->asArray()
->one();
},
new DbDependency(['sql' => 'SELECT `lastModified` FROM `' . News::tableName() . '` WHERE `alias`="' . $title . '"'])
);
return $this->render('show', compact('news'));
}
}