Проект

Общее

Профиль

Обертка для кэширования данных

Из документации:

// 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'));
    }
}