APC is a simple and yet powerful PHP extension that does just that: caching. What for? Suppose you would have some piece of code that fetches some data from a table, and since you don’t use JOIN because you loose scalability, you’ll have to do some more SELECTs, and then format each row to be ready for display.
The other advantage is that it caches the compiled PHP source code in memory, serving it a lot faster.
Now if 100 users to this in one minute, (1) your server will fail to serve the pages because (2) it is doing a very complicated task that outputs the same result throughout the minute. This is where APC comes handy. You can save the retrieved data in the APC cache which holds it in memory and then just serve it to whoever asks for it.
The first thing to do is check if the APC extension is installed and running. For that you can look at phpinfo()’s result and check for APC. If it’s not, you should look in the php.ini file for the extension directive to be uncommented.
Using the APC cache requires three things:
- a name (key) for the piece of information saved;
- the actual data;
- the TTL (time to live): how many seconds the information will be held in the cache.
The syntax to add data in the cache is as follows:
bool apc_add ( string $key, mixed $var [, int $ttl=0] )
So, $key is the name under which we’ll find the saved info, $var is the actual data and $ttl is an optional parameter to specify a time to live. If this function returns FALSE, something went wrong and the information isn’t cached. You’ll have to have some sort of fallback and never rely on the fact that you’re info is safe in the cache.
To retrieve the cached data, use apc_fetch():
mixed apc_fetch ( string $key [, bool &$success ] )
It’s that easy. Just ask for the saved key and you get it. If it’s not found or something goes wrong, this function returns FALSE and if the optional parameter was specified, sets that one too to FALSE.
That’s it. You have an up and running cache system.
Good practice: Regarding the usage of cache, there are two things you should keep in mind:
- you should build your code like there can be no caching done; that means 100% fallback. If the APC extension is disabled, your code should work.
- the specific APC caching functions should be wrapped up in some generic functions that call the actual functions. This thing will make you go light up a candle when – at some point – you’ll be switching to memcached or some other kind of caching, because you’ll only have to modify the contents of these wrapper functions, and not search & replace the entries in all your code.
Here’s an example on how to acomplish both these things:
function cacheWrite( $sKey, $mData, $iTtl ) { if( function_exists( 'apc_add ' ) ) { // we have APC return apc_add( $sKey, $mData, $iTtl ); } return FALSE; } // END func cacheWrite() function cacheRead( $sKey ) { if( function_exists( 'apc_fetch' ) ) { // we have APC return apc_fetch( $sKey ); } return FALSE; } // END func cacheRead() //---------- code that read/writes $sKey = md5( $sQuery ); // same query will return same data, whithin minutes if( ( $mData = cacheRead( $sKey ) ) === FALSE ) { // info not cached $mData = functionThatMakesUpTheData(); cacheWrite( $sKey, $mData, 600 ); // cache the data for 10 minutes } // done, here we have our data, no matter if caching functions are available // or not, if the info is in the cache or not
And to make it even more fun, APC comes with a nice online page that gives you all the information you need, including cache hits & misses (misses happen when the cache memory is full), a list of all the user-space cached data along with options to view or delete one or all the entries and much more.