How To Get Page Fragment Cache Id In An Action

I run into a problem lately when trying page fragment cache in my project. I use CFileCache for the job.

The code in the view file(simplified):


        

if($this->beginCache('search',  array('varyByParam'=>array('keyword')))) {

        if(!empty($data)) {

       

            if($data as $v) {  //The data is fetched from database and passed by the action

                echo $v;

            }        

        }    

                 $this->endCache();

} 




Refresh the page and the fragment is successfully saved in runtime/cache.

Then I tried to stop sql execution in the action if cache is available:


       

       $cachedData = Yii::app()->cache->get('search');

        

       if(!$cachedData) {

          $dataModel = new DaoModel;

	  $data =  $dataModel->fetchFromDatabase();

       }


       $this->render('viewFile', array('data'=>$data));



$cacheData is always empty. Anyone can tell me why? And how can I check if a page fragment cache exists?

Hi dentrite, welcome to the forum.

When you set ‘varyByParam’ option, the cached entry has an id made from ‘id’ AND the given parameters. For example, if ‘keyword’ is ‘foobar’, then the cache id will be made from ‘search’, ‘keyword’ and ‘foobar’, and when ‘keyword’ is ‘buz’ then from ‘search’, ‘keyword’ and ‘buz’. In this way you will have different cache entries for each different keyword.

http://www.yiiframework.com/doc/guide/1.1/en/caching.fragment#caching-options

So, you can’t retrieve the previously cached entry just by “Yii::app()->cache->get(‘search’)”.

I would rather perform the db access in between beginCache and endCache. :)

softark, thanks for the reply.

I kind of understand what you explain in the first part. However, if I perform db access in between beginCache and endCache, that means perform it in the view file, does it violate the MVC principle—separate concerns? What’s more, the db access code is a bit lengthy here(restructure data from several tables). Is there any easy way to check whether a fragment cache is available in the controller part.

Of course we don’t want to write a lengthy code to construct a SQL or a CDbCriteria directly in the view script.

But I think that calling some model or controller method in the view script is completely legitimate, especially when the method is well encapsulated and given a simple and clean interface.

For example, you can see a CGridView widget that calls $model->search() in a Gii generated admin view.

As for the checking of the cache entry, I don’t know much about it right now. We have to get the constructed key in order to check the entry. The logic of creating a cache key is implemented in COutputCache. beginCache() is a wrapper of it … but as long as I see in the reference, there’s no easy way to get the constructed key. I might be wrong in this, though.

But, in the first place, you don’t need to check the cache entries 2 times. Just calling beginCache() for checking the cache should be enough. :)