Fragment Caching question

Hello.

I am using fragment caching for some categories printing, so this is the example code:




if($this->beginCache('catsTree', array('duration'=>800)))

{

    //print cats	    

    $this->endCache();

}



And everytime I reload the page $this->beginCache return true… which is unexpected result.

I tested it with simple changing of content in "print cats" code and it seems no cache is available.

Am I doing it wrong or missing something?

Yii version is 1.1.2

Thanks!

Did you configure a cache component in your main.php? E.g. APC:


    'components'=>array(

        'cache'=>array(

            'class'=>'CApcCache',

        ),



Oh… of course I missed something…

Thanks man.

While we are in cache topic, I found this situation:

include(Chtml.php) [<a href=‘function.include’>function.include</a>]: failed to open stream: No such file or directory

Wrong typed CHtml (with small "h") was after cached section in the same view file.

I fixed it, but is there a reason that this error hasn’t appeared before adding “if($this->beginCache…”? :)

Maybe CHtml was included already, because it was used in cached section.

Are you on Windows? My guess then would be: The filesystem itself is case independent, so if you use pure PHP everything wents fine. But APC is more sensible with upper lower cases of cached class files.

Just make sure your filenames always matches exactly and you should never have a problem on Windows AND Linux.

No, it’s Linux hosting.

I mean that when include files in Case Sensitive OS/server, this is a problem, but when just call CHtml twice (second one with lower case like “Chtml”) it’s working and in my situation this was unexpected issue, because cache section actually hide part of my PHP code (including CHtml method). :)

However, the problem is fixed and the cache is working now. :)

Ah, right. That explains it pretty good.

Since the name of this topic is pretty general, I would like to ask one more question about fragment caching :)

In my application I retrieve some information from other site every 3 hours, insert it into database and make Yii::app()->cache->flush() to update a block on a site containing this information. Since it is the only block being cached, I can flush all cache info. But what if I have many cached blocks and I want to flush only one block’s cache? I tried:




Yii::app()->cache->delete('BlockId');


// or


Yii::app()->cache->delete('Yii.COutputCache.BlockId');



but both lines don’t delete fragment cache file. I did a quick look at how file name is generated and it looks more complex than previous two lines.

Any tips? :) Thanks.

The way this is supposed to happen is by using a CCacheDependency, i think. Maybe a CGlobalStateCacheDependency helps here.

Hi again.

I have another problem.

When use cache for fragment of sitewide view (like sidebar), cache file is not the same for different site links.

For example, I add a link in sidebar and this link appear in one page, but on the index for example is missing (because of cache).

And on the page where exist is actually cached too, coz if i remove the link, it appear on this page during cache duration.

Any idea why this is happened? :)

Thanks!

@BornToDrink:

From what i understand, you should take a look at caching dynamic content. Like: Most parts of your cached content (sidebar) stay the same, except for some dynamic parts (some links…)

P.S.: Maybe a better title for this topic would be “Everything you always wanted to know about caching* (*But where afraid to ask)” ;D

:D

Thank you for joining this topic again.

But let me explain what exactly is the problem (I reproduced the issue with demo blog).

So to reproduce this issue, please follow these steps:

  1. Download Yii (1.1.3 is OK)

  2. Open demos/blog/protected/config/main.php and add these lines in "components" section:




'cache'=>array(

    'class'=>'CFileCache',

),



  1. Open demos/blog/protected/views/layouts/column2.php and add these lines:



if($this->beginCache('somecache', array('duration'=>600)))

{

	echo time();

	$this->endCache();

}



  1. After save both files, open home page and see the timestamp in sidebar, now go to "Comments" link on first blog post - timestamp is different!

Now you can click on index and “Comments” pages to see that we have different cache fragments… (timestamp is not changed until 600 secs, but in both pages timestamp is different)… which is the issue in my case. :)

Is this again configurable issue or it’s a bug? :)

Interesting :). Would not have that expected that either.

beginCache() uses the COutputCache widget internally. It has some varyBy* properties. They define the condition, when another fragment should get cached even for the same id. And here you see that varyByRoute defaults to true. The problem should be gone if you use:


if($this->beginCache('somecache', array('duration'=>600,'varyByRoute'=>false)))

Ahh… :)

Now everything is OK. Thanks again. :)

Yesterday I made some tests with Apache Bench and the caching technique improve the performance on my application with about 10-25%, depending on current page. Which is really nice. :)