blog.Resource

Archive:

News-Feeds:


RSS 2.0
RSS 0.91
RDF
ATOM 0.3
June 7, 2010

Using Cache in Extensions

Category: Steffen Kamper, TYPO3, Core

TYPO3 comes along with great cache. It's used in core at many places to speed up calls that need time to calculate and are used often.

This cache can be very useful in own extensions for the same reasons.

Usage of cache is very easy, and i want to show you how to do this. We will use cache_hash. You don't have to take care about the caching framework, read and save cache entries will be done by core.

Now let's look how we use the cache, here are a getter and a setter you may use in your extension. Remember that cache data is always an array, if you want to save strings, you have to put them into an array. The cache saving serializes the array, if you read, you get the serialized array, and you have to unserialize it for usage.

/**
 * Gets the cache entry
 *
 * @param string $key cache key
 * @param string $identifier unique identifier
 * @return string serialized cache entry
 */
protected function getCache($key, $identifier) {
    $cacheIdentifier = 'MyExtension-' . $identifier;
    $cacheHash = md5($cacheIdentifier . $key);
    return t3lib_pageSelect::getHash($cacheHash);
}

/**
 * Stores data in cache
 *
 * @param string $key cache key
 * @param string $identifier unique identifier
 * @param array $data your data to store in cache
 */
protected function setCache($key, $identifier, $data) {
    $cacheIdentifier = 'MyExtension-' . $identifier;
    $cacheHash = md5($cacheIdentifier . $key);
    t3lib_pageSelect::storeHash(
        $cacheHash,
        serialize($data),
        $cacheIdentifier
    );
}

That's all. Usage is very simple, let's use it in a function for getting some data:

public function getSpecialData($param1, $param2) {
    $key = $param1 . $param2;
    $cacheContent = $this->getCache($key, 'getSpecialData');
    if (!$cacheContent) {
        $result = array();
        // process data and fill $result
        // Now store the $result in cache and return
        $this->setCache($key, 'getSpecialData', $result);
        return $result;
    } else {
        return unserialize($cacheContent);
    }
}

That's all. The reason why i compose the identifier with a hardcoded string is, that you may use this from different functions. This helps you to identify the cache entries. i prefer to compose the identifier with "extkey-functionName".

If you don't use caching framework, you'll find your entires in the DB table cache_hash, with DB cache framework the data is splitted and you find your identifiers in DB table cachingframework_cache_hash_tags.

The cache entries will be cleared with the normal "Clear Cache" commands.

Happy caching ;-)

 


comments

comment #1
Gravatar: Julian Kleinhans Julian Kleinhans June 7, 2010 11:46
Hey Steffen,

nice article! thanks for sharing knowhow :-)

comment #2
Gravatar: Alex Kellner Alex Kellner June 7, 2010 11:50
Thank you for the article. Will share it via Twitter...

comment #3
Gravatar: Ingo Ingo June 7, 2010 12:02
I don't think this is a practice one should follow. Don't put your cache data in the core's cache store... Instead use the caching framework to create an own, dedicated cache store. Don't abuse functions / the APIs just because you can.

comment #4
Gravatar: Susanne Susanne June 7, 2010 12:21
@Ingo: I'd be interested in how to do that. Is there an article / documentation about that?

comment #5
Gravatar: Steffen Kamper Steffen Kamper June 7, 2010 12:39
@Ingo I don't see a problem using the cache_hash table. There is an option not to use the caching framework. if this is set, your own caching methods will fail.

Sure you can introduce own caching methods with the caching framework, then you also have to introduce methods for flush the cache. So imho it depends on the complexity you need for your application.

comment #6
Gravatar: Dan Osipov Dan Osipov June 7, 2010 13:43
Here is how you can use the framework to create your own cache:
http://danosipov.com/blog/?p=322

comment #7
Gravatar: Christian Kuhn Christian Kuhn June 8, 2010 02:39
@susanne, @dan:
Even more simple (especially for frontend tasks): Use the enetcache extension with the caching framework and get a BE module with visual debugging of cache entries and flow for free. enetcache is in TER, extensive documentation and examples included.

basic usage:
t3lib_div::makeInstance('tx_enetcache')->set($identifier, $data, $tags, $lifetime);

t3lib_div::makeInstance('tx_enetcache')->get($identifier);

comment #8
Gravatar: Jonas Jonas June 21, 2010 07:18
What about clearing this cache? Is it cleared with other cached data of the current page?

It's important to have the cache page related, so it gets cleared by the TYPO3 cache system as soon as it thinks the cache of this page is cleared... (in example if you have a news plugin on that page and the clearCache command set...)

comment #9
Gravatar: Jimmy Jimmy June 24, 2010 15:29
Hi Jonas

To clear cache You may used following: codesetCacheReg($value, $key='reg1')
clearCacheByPage ($uid)
clearCacheByReg ($value, $key='reg1', $pid=0)
I hope it would be useful for you.

comment #10
Gravatar: Torebki Damskie Torebki Damskie July 4, 2010 23:49
i'm still searching ways to improve performance of my shop and this is another great idea to try

Sorry, comments are closed for this post.