Yii2 Caching Techniques

Efficient caching is essential for improving the performance of Yii2 applications. Yii2 provides multiple caching mechanisms, including file-based, database, memory, and fragment caching. This tutorial covers different caching strategies and how to implement them in Yii2.


Types of Caching in Yii2

Yii2 supports various caching techniques, including:

  1. Data Caching – Stores data in cache to avoid recalculating it.
  2. Fragment Caching – Caches specific parts of a view.
  3. Page Caching – Caches entire pages to improve response time.
  4. Query Caching – Caches database query results.
  5. HTTP Caching – Uses browser and server cache headers to improve efficiency.

Configuring Cache in Yii2

Yii2 supports multiple cache components, such as FileCache, DbCache, and MemCache. Configure the cache component in config/web.php (Basic Template) or common/config/main.php (Advanced Template).

File Cache (Default)

'components' => [
    'cache' => [
        'class' => 'yii\caching\FileCache',
    ],
],

File-based caching is suitable for small applications but may not perform well under high load.

Database Cache

'components' => [
    'cache' => [
        'class' => 'yii\caching\DbCache',
        'db' => 'db', // Database connection
        'cacheTable' => 'cache', // Table name
    ],
],

Run the following command to create the cache table:

php yii cache/schema

Database caching is useful when multiple application instances share cached data.

Memcached

'components' => [
    'cache' => [
        'class' => 'yii\caching\MemCache',
        'servers' => [
            ['host' => '127.0.0.1', 'port' => 11211, 'weight' => 100],
        ],
    ],
],

Memcached is suitable for high-performance applications with distributed caching needs.


Data Caching

Data caching allows you to store complex calculations, API responses, or database results in the cache.

Storing and Retrieving Cached Data

$key = 'expensive_data';
$data = Yii::$app->cache->get($key);

if ($data === false) {
    $data = ExpensiveCalculation(); // Example function
    Yii::$app->cache->set($key, $data, 3600); // Store for 1 hour
}

This avoids recomputing data on every request.

Deleting Cached Data

Yii::$app->cache->delete('expensive_data');

To clear all cache:

Yii::$app->cache->flush();

Fragment Caching

Fragment caching allows caching a specific part of a view.

Using Fragment Cache in Views

if ($this->beginCache('sidebar', ['duration' => 3600])) {
    echo $this->render('sidebar');
    $this->endCache();
}

This caches the sidebar partial view for 1 hour.

Adding Cache Dependency

if ($this->beginCache('sidebar', [
    'duration' => 3600,
    'dependency' => [
        'class' => 'yii\caching\DbDependency',
        'sql' => 'SELECT MAX(updated_at) FROM news',
    ],
])) {
    echo $this->render('sidebar');
    $this->endCache();
}

This ensures the cache is invalidated whenever news is updated.

Fragment Caching in Search Models (Handling Dynamic Filters)

To cache different results for different filters, we generate a cache key dynamically based on the search parameters.

Use a Unique Cache Key Per Filter Combination

$cacheKey = 'search-results-' . md5(json_encode(Yii::$app->request->queryParams));

if ($this->beginCache($cacheKey, ['duration' => 3600])) {
    echo GridView::widget(['dataProvider' => $dataProvider, 'filterModel' => $searchModel]);
    $this->endCache();
}

How This Works:

  • Yii::$app->request->queryParams holds all the filter inputs.
  • We convert it to a unique string using json_encode().
  • Then, we hash it using md5() to create a unique cache key.
  • Now, different filter conditions will generate different cache keys, ensuring correct results for each search.

Page Caching

Page caching caches the entire page, reducing processing time for static pages.

Enable Page Caching in Controller

public function behaviors()
{
    return [
        'pageCache' => [
            'class' => 'yii\filters\PageCache',
            'only' => ['index'],
            'duration' => 3600,
        ],
    ];
}

This caches the index action for 1 hour.


Query Caching

Query caching stores database query results to reduce database load.

Using cache() Method:

$users = User::find()->cache(3600)->all(); // Cache query results for 1 hour

Enable Query Caching

$cache = Yii::$app->cache;
$data = Yii::$app->db->cache(function ($db) {
    return $db->createCommand('SELECT * FROM posts')->queryAll();
}, 3600);

This caches the query results for 1 hour.

Using Cache Dependency

$dependency = new \yii\caching\DbDependency([
    'sql' => 'SELECT COUNT(*) FROM posts',
]);

$data = Yii::$app->db->cache(function ($db) {
    return $db->createCommand('SELECT * FROM posts')->queryAll();
}, 3600, $dependency);

This invalidates the cache when the number of posts changes.


HTTP Caching

Yii2 supports HTTP caching using headers to reduce load on the server.

Enable HTTP Caching in Controller

public function behaviors()
{
    return [
        'httpCache' => [
            'class' => 'yii\filters\HttpCache',
            'only' => ['index'],
            'lastModified' => function () {
                return time();
            },
            'etagSeed' => function () {
                return Yii::$app->cache->get('etag_seed');
            },
        ],
    ];
}

This adds Last-Modified and ETag headers to the response.


Best Practices for Yii2 Caching

  • Use fragment caching for reusable UI components.
  • Use query caching to reduce database load.
  • Use dependency-based caching to invalidate cache intelligently.
  • Use memory-based caching (Redis, Memcached) for high-performance applications.
  • Regularly flush cache when deploying updates.

Conclusion

Yii2 provides multiple caching mechanisms to improve application performance. Choosing the right caching strategy depends on your application’s needs. Implementing caching effectively can reduce server load and enhance user experience.