jump to navigation

Cache objects component March 15, 2006

Posted by rossoft in CakePHP.
trackback

Usage:
$cacheName = “my_controller/$id”;
$data=$this->cache->read($cacheName);
if (!$data) //if isn’t on cache…
{
       $this->MyModel->id=$id;
       $data=$this->MyModel->read();
   
   $this->cache->write($cacheName,$data,’+1 hour’); //save to
cache and set expiration date. It will be deleted automatically after
expiration even if it isn’t readed anymore
}

Source code

<?php
/*
 * Cache Objects component.
 * Read and write to cache with “garbage collector”
 * It will delete the expired ones automatically even
 * if they aren’t accessed.
 * You have to define the expiration date at write.
 *
 * It’s thread safe with mutex.
 *
 * @author      RosSoft
 * @version     0.2
 * @license        MIT
 *
 */

define(‘CACHE_COMPONENT_INFO_FILENAME’,CACHE .’cache_component_info’ );
define(‘CACHE_COMPONENT_INFO_DIR’,’cache_component_objects/’ );

class CacheObjectComponent extends Object
{
    /**    Mutex variable */   
    var $mutex;
   
    /** Info of items */
    var $info;
   
    /** array of items added / modified */
    var $modified;
   
    /** array of items deleted */
    var $deleted;
   
    function __construct()
    {
        $this->modified=array();
        $this->deleted=array();
       
        $this->_load_info();
    }
   
    function _load_info($lock=true)
    {
        //Load the cache info file       
        if (file_exists(CACHE_COMPONENT_INFO_FILENAME))
        {
            if ($lock)
            {
                $this->_mutex_lock();
            }           
            $this->info=unserialize(file_get_contents(CACHE_COMPONENT_INFO_FILENAME));
            if ($lock)
            {
                $this->_mutex_unlock();   
            }           
        }
        else
        {
            $this->info=array();   
        }                   
    }
   
    /**
     * save the cache info
     */
    function _write_info()
    {
        if (count($this->modified)>0
            || count($this->deleted)>0)
        {       
            $this->_mutex_lock();
            $this->_load_info(false);       
            foreach ($this->modified as $name=>$value)
            {
                $this->info[$name]=$value;
            }
           
            foreach ($this->deleted as $name)
            {
                unset($this->info[$name]);
            }           
            file_put_contents(CACHE_COMPONENT_INFO_FILENAME,serialize($this->info));
            $this->modified=array();
            $this->deleted=array();
            $this->_mutex_unlock();
        }           
    }

    /**
     * Locks a mutex
     */   
    function _mutex_lock()
    {       
        $this->mutex = @fopen(CACHE_COMPONENT_INFO_FILENAME . ‘.lock’, ‘w’);       
        if ( false == $this->mutex)
        {
            return false;
        }
        flock($this->mutex, LOCK_EX);
        return true;       
    }

    /**
     * Releases a mutex
     */   
    function _mutex_unlock()
    {
        // Release write lock.
        flock($this->mutex, LOCK_UN);
        fclose($this->mutex);
        @unlink(CACHE_COMPONENT_INFO_FILENAME . ‘.lock’);
    }   
   
    function __destruct()
    {
        //delete expirated files               
        $names=array_keys($this->info);
        foreach ($names as $name)
        {           
            if ($this->expired($name))
            {
                @unlink(CACHE . CACHE_COMPONENT_INFO_DIR  . $name);
                unset($this->info[$name]);
                $this->deleted[]=$name;
            }
        }
        $this->_write_info();
       
    }       
   
    /**
     * Read a data from cache file
     * @param  string $name File path within /tmp/cache to read the file.
     * @return mixed  The contents of the temporary file. False if expired
     */   
    function read($name)
    {
        if ($this->expired($name))
        {
            return false;
        }
        else
        {
            return unserialize(cache(CACHE_COMPONENT_INFO_DIR . $name,null,’+1 year’));
        }       
    }
   
    /**
     * Write data to cache file
     * @param  string $name File path within /tmp/cache to save the file.
     * @param  mixed  $data    The data to save to the temporary file.
     * @param  mixed  $expires A valid strtotime string when the data expires.
     */   
    function write($name,$data,$expires=’+1 day’)
    {
           $expires = strtotime($expires);
        $this->info[$name]=$expires;
        $this->modified[$name]=$expires;   

        cache(CACHE_COMPONENT_INFO_DIR . $name,serialize($data)); //writes to cache
                   
    }
   
    /**
     * Tests if a cache file has expired
     * @return boolean True if expired
     */
    function expired($name)
    {
        if (!isset($this->info[$name]))
        {
            return true;
        }
        else
        {
            return ($this->info[$name]<time());
        }   
    }

    /**
     * Clears all the cache files
     */   
    function clear()
    {       
            $this->_write_info();
            foreach (array_keys($this->info) as $name)
            {
                @unlink(CACHE . CACHE_COMPONENT_INFO_DIR  . $name);
                $this->deleted[]=$name;                                                           
            }                                       
            $this->_write_info();
    }

}         
?>

Advertisements

Comments»

1. RosSoft » IP to Country component (Geo Location) - March 29, 2006

[…] 3. Download the CacheObject component […]

2. nrm - August 2, 2006

thanks! it’s great!

3. marcus - November 22, 2007

Thanks for the great component. Just not sure where I should place it.

Can you help please?

4. CakePHP Additives | Candes Projects | Cristian Neagu - Web designer & developer - February 26, 2008

[…] Cache components […]

5. Marcus - May 20, 2008

found the location to place it finally thanks.

Would it be a bad idea, to query the db and store the results in the cache for one full day? I am currently writting a site map controller which generates links to the site wide. Just asking because if that is a bad idea will have to do something different.

I wrote it for the site: tri-c-a.com

Check it out at: http://www.tri-c-a.com/sitemap.xml

Steve - August 21, 2009

It would be nice if you found the answer, to mention it in your comments rather than just “found the location to place it..”. That would help people encountering the same issue and needs an answer.

6. charbel - February 4, 2011

hi, this class doesn’t clean the expired files.
any help plz?


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: