Home arrow PHP arrow Page 2 - Creating an Extensible Caching System in PHP

Building an APC wrapper - PHP

In this part of the series, I demonstrate that the use of the “Plug-in” pattern in the construction of an extensible caching system is actually much simpler than many people might think. [Editor's note: this article was published out of sequence; it's actually the third in the series, and comes before yesterday's "HTML5 Client-Side Cache in PHP."]

TABLE OF CONTENTS:
  1. Creating an Extensible Caching System in PHP
  2. Building an APC wrapper
By: Alejandro Gervasio
Rating: starstarstarstarstar / 2
February 03, 2011

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

As you may have already guessed, building a wrapper class for the APC PHP extension is a pretty straightforward process. The most relevant point to stress here is that this wrapper must be an implementer of the previous “Cacheable” interface, so it can be easily swapped at runtime by client code consuming different cache back-ends.

Having clarified that concept, the APC class looks like this: 

(Cache/ApcCache.php)

<?php

namespace Cache;

class ApcCache implements Cacheable
{
    /**
     * Save data to the cache
     */
    public function set($key, $data)
    {
        if (!apc_store($key, $data)) {
            throw new ApcCacheException('Error saving data with the key ' . $key . ' to the cache.');
        }
        return $this;
    }
   
    /**
     * Get the specified data from the cache
     */
    public function get($key)
    {
        if ($this->exists($key)) {
            if (!$data = apc_fetch($key)) {
                throw new ApcCacheException('Error fetching data with the key ' . $key . ' from the cache.');
            }
            return $data;
        }
        return null;
    }
   
    /**
     * Delete the specified data from the cache
     */
    public function delete($key)
    {
        if ($this->exists($key)) {
            if (!apc_delete($key)) {
                throw new ApcCacheException('Error deleting data with the key ' . $key . ' from the cache.');
            }
        }
        return $this;
    }
   
    /**
     * Check if the specified cache key exists
     */
    public function exists($key)
    {
        return apc_exists($key);
    }
   
    /**
     * Clear the cache
     */
    public function clear($cacheType = 'user')
    {
        return apc_clear_cache($cacheType);
    }       
}

 

(Cache/ApcCacheException.php)

<?php

namespace Cache;

class ApcCacheException extends Exception{}

If you've ever worked with the APC extension, then the definition of the above “Apc” class should be pretty familiar to you. As I just mentioned, this class is nothing but a basic wrapper for the most important functions included with the extension, which provides enough functionality for saving, fetching and deleting data from the opcode cache. Of course, it’s possible to improve the implementation of this class; in this case, however, I’m going to keep it simple, so that you can more quickly grasp how it works.

Although it’s valid to note that this concrete cache backend can be used perfectly as a standalone component, my goal here is to demonstrate how to utilize it as a “plug-in.” To do so, it’s necessary to define a client class capable of injecting different cache back-ends according to specific requirements. Given that, in the next segment I’m going to define such a client, which as you’ll see in a moment, will consist of a simple cache manager class.

To learn the full details regarding the definition of this cache manager, just keep reading.

Managing different cache back-ends at runtime: developing a cache handler class

While the name may sounds somewhat intimidating, the truth is that building a “cache manager” class is an extremely simple process that can be accomplished in a snap. The only requirement that this class must meet is that it must be capable of working with multiple cache back-ends without having to modify its original implementation.

Thanks to the model imposed by the “Plug-in” pattern, this can be easily achieved by combining the power of Composition (read Dependency Injection) with the one provided by the “Cacheable” interface previously defined.  

If this explanation doesn’t ring any bells for you yet, take a look at the source code of the following cache handler class; it will hopefully clear things up for you:

(Cache/CacheHandler.php)

<?php

namespace Cache;

class CacheHandler
{
    protected $_cache;
   
    /**
     * Constructor
     */
    public function __construct(Cacheable $cache)
    {
        $this->_cache = $cache;
    }
   
    /**
     * Add the specified data to the cache
     */
    public function set($key, $data)
    {
        return $this->_cache->set($key, $data);
    }
   
    /**
     * Get the specified data from the cache
     */
    public function get($key)
    {
        return $this->_cache->get($key);
    }
   
    /**
     * Delete the specified data from the cache
     */
    public function delete($key)
    {
        $this->_cache->delete($key);
    }         
}
 
There you have it. As you can see from the above code sample, the “CacheHandler” class takes through its constructor a generic cache backend, which is first stored as a protected property and then used within its “set(),” “get()” and “delete()” methods. Even though it's simple, this implementation is very flexible because it permits you to use different cache back-ends, as long as they implement the  “Cacheable” interface.

Finally, here’s an example that shows how to use this cache handler together with the “Apc” class shown before (don’t worry about the definition of the autoloader below, as it’s the same one we've used earlier in this series): 

// include the autoloader
require_once 'Autoloader.php';
Autoloader::getInstance();

use CacheApcCache as ApcCache,
    CacheCacheHandler as CacheHandler;

// cache some data using APC
$cacheHandler = new CacheHandler(new ApcCache);
$cacheHandler->set('fname', 'Julie')
             ->set('lname', 'Smith')
             ->set('email', 'julie@domain.com');
            
// display the cached data
echo ' First Name: ' . $cacheHandler->get('fname') .
     ' Last Name: ' . $cacheHandler->get('lname') .
     ' Email: ' . $cacheHandler->get('email');

As this example shows, saving and fetching some data from the opcode APC cache is ridiculously simple. Nevertheless, the most important detail to note here is that the APC wrapper can easily be substituted with another cache “plug-in,” be it one that uses the file system or one that relies on shared memory. This is precisely the advantage of using the “Plug-in” pattern!

But I’m getting ahead of myself, since the construction of an additional cache backend will be covered in depth in the next tutorial. Meanwhile, feel free to introduce your own tweaks and improvements to all of the sample classes defined so far, something that will help you acquire a better understanding on this pattern.

Final thoughts

In this third installment of the series, I demonstrated that the use of the “Plug-in” pattern in the construction of an extensible caching system is actually much simpler than many people might think. In fact, to make my point and demonstrate that the system is really “pluggable,” it’s necessary to create another cache backend, aside from the basic APC wrapper that you saw before.

Well, that’s exactly what I will do in another part of the series. This new cache backend will use the features provided by the flashy local storage mechanism included with HTML5.



 
 
>>> More PHP Articles          >>> More By Alejandro Gervasio
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PHP ARTICLES

- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: