caching controllers with filters()

Hello, this article will describe some aspects about caching controllers with filters() method in your controller. And I will describe some problems I meet when using this approach for caching, the main problem was

how can i invalidate a cache for specific action?

I googled the forum

asked on IRC and SO but I didn't find an answer, therefore decided to write this article.

Our first task is to invalidate a cache for specific page. When you use filters() and COutputCache in your controller you will find some restrictions of this approach.

  1. If you change your filters() caching settings, you need to invalidate your cached data, before your filters() changes will be in action.
  2. You can't invalidate a specific page or specific action, and sometimes you don't need and don't want to flush whole cache, for example: if you're changing your duration option.
  3. If you change some dependency in your filters() you also don't need and don't want flush whole cache.

Yii doesn't have an implemented function for this and i need to make it. At first we need to create our own Cache Component.

Note: I will use CFileCache component, because i use CFileCache as my main cache. But it should work with every cache class.

I created MyCache.php file in ./protected/components/

class MyCache extends CFileCache
{
    public function getValue($key) {
        if( isset( $_GET['flush'] ) ) 
            $this->deleteValue($key);
        return parent::getValue($key);
    }
}

Next step, you need to change your cache class in your config.

'cache'=>array(
    //'class'=>'system.caching.CFileCache',
    'class'=>'MyCache',
),

That's all. Now when you want to invalidate a specific page cache, you just need to add a flush variable into your URI request. ex: To invalidate just index page from the cache, use this url: www.myyiisite.com/?flush . That's all, index page is invalidated and new cache settings is now in action.

Drowbacks:

  1. I can't invalidate a controller cache. If you have 10 controllers in your app, and change your filters() code, you don't want to flush whole cache. You want to invalidate the cache just for this controller. And Yii can't.