caching controllers with filters()

You are viewing revision #4 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version.

next (#5) »

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

how can i invalidate a cache for specific action?

I googled forums

how to delete whole-page cache from cache?

flush controller cache

Is there any way to invalidate cached version of a whole-cached page?

asked on IRC and SO but i didn't find an answer, therefore i 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 cant 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 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 must 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: i want to invalidate just index page from my cache, i use next url: www.myyiisite.com/?flush . That's all, index page is invalidated and new cache settings now in action.

Drowbacks:

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