Problem with cache

In my blog I will do fragment caching.

In my post view I have this code.




   <?php

    if($this->beginCache('post_content'.$model->id, array('cacheID'=>'cacheBlog','duration'=>3600,

      'dependency'=>array(

        'class'=>'system.caching.dependencies.CExpressionDependency',

        'expression'=>$model->modified)

    ))) {

  		$this->beginWidget('CMarkdown', array('purifyOutput'=>true));

  		echo $model->content_summary.'<br>';

  		echo $model->content;

  		$this->endWidget();

  		$this->endCache();

}

?>



The data will cache correct.

But when I updated my post I get the unchanged data from cache. (The $model->modified has changed)

I don’t know what I am doing wrong.

  1. ‘expression’ should be a string with PHP code. What happens in your case is that $model->modified is evaluated once and then the result is used as expression - which never changes again. So you should put the expression in single quotes, like ‘$model->modified’

  2. It still won’t work though, because $model will no longer be assigned at the point when the expression is evaluated later. So you need to find a “standalone” expression, which always works.

Thank you for your answer.

OK I have understand what you mean but I don’t know how can I realize this.

I my cache table I have the right modified date:

My understanding is now that it compare the new value of $model->modified with the expression result in the cached data.

Now I have try it with CDbCacheDependency and this work for me




   <?php

    if($this->beginCache('post_content'.$model->id, array('cacheID'=>'cacheBlog','duration'=>3600,

      'dependency'=>array(

        'class'=>'system.caching.dependencies.CDbCacheDependency',

        'params'=>array(':id'=>$model->id),

        'sql'=>"SELECT modified FROM blog_post WHERE id=:id",

       ),


    ))) {

  		$this->beginWidget('CMarkdown', array('purifyOutput'=>true));

  		echo $model->content_summary.'<br>';

  		echo $model->content;

  		$this->endWidget();

  		$this->endCache();

}

?>



I think this is good enough but how can I achieve this with CExpressionDependency ?

I see that I can use a callback but where I must create the callback function (in which scope I mean)

Only for interest user I profile the cache efficients:




 <div>

  <?php 

  Yii::beginProfile('without_cache');

    $this->beginWidget('CMarkdown', array('purifyOutput'=>true));

  		echo $model->content_summary.'<br>';

  		echo $model->content;

  		$this->endWidget();

  		Yii::endProfile('without_cache');

   ?>

  </div>

  

  <div class="content">

    <?php

    Yii::beginProfile('cache');

    if($this->beginCache('post_content'.$model->id, array('cacheID'=>'cacheBlog','duration'=>3600,

      'dependency'=>array(

        'class'=>'system.caching.dependencies.CDbCacheDependency',

        'params'=>array(':id'=>$model->id),

        'sql'=>"SELECT modified FROM blog_post WHERE id=:id",

       ),


    ))) {

  		$this->beginWidget('CMarkdown', array('purifyOutput'=>true));

  		echo $model->content_summary.'<br>';

  		echo $model->content;

  		$this->endWidget();

  		$this->endCache();

}

Yii::endProfile('cache');

?>

  </div>



This is the blog post test I use:

Execution time:

‘cache’= 0.01361 s

'without_cache = 0.15231 s

I don’t see a way to use a PHPExpression in such a case because the only way to know if something has changed is the database (or some cache key). As Mike already stated: $model is not a valid variable for a PHP expression. At the time the cache is evaluated there is no such variable. You can use an anonymous function, query the database or something like that in there but using the SQL dependency is so much easier. The funny thing about this is that Mike already published an extension that can be used for your scenario called “flushable”: http://www.yiiframework.com/extension/flushable. Every time you save a post you could then flush your cache to refresh the entries

Thank you for your answer.

I want to look the flushable extension but I don’t know how I can extract the tgz file on my ubuntu server.

I try it with




sudo tar -zxf flushable-1.1.1.tgz



but I get the following error:

this does not like a tar archive

Can you help me?

Hmm. I just verified, and the archive extracts just fine. Try with tar xvzf flushable-1.1.1.tgz

I try this but I get the same errror

tar: This does not like a tar archive

tar: Skipping to next header

tar: Error exit delayed from previous errors