Jump to content
×
×
  • Create New...

Class - Gestion du Cache


Recommended Posts

Niveau requis Intermédiaire

Temps estimé : 30 minutes

Bonjour,

 

Le code que je vais proposer ici est une classe de gestion de cache. Je l'ai mise ici parce que c'est du web, mais en théorie ça va aussi dans l'autre partie car c'est de l'OO. Enfin, passons.

 

Class PHP

 

Révélation
<?php
/**
 * Implements cache management
 *
 * @file $Id$
 */
class Cache
{
        const DIR = 'cache/';
 
        protected static $cachedFiles = null,
                $actual = null,
                $dirPrefix = '',
                /* @var string Var prefix. NOTE : if not empty, followed by an underscore ! (ie with varPrefix = '%%cache%%' and varName = 'test', will result in '%%cache%%_test' */
                $varPrefix = '';
        protected $name = null,
                $vars;
 
 
        /**
         * sets dir prefix.
         * The dir MUST exist.
         *
         * @param string $prefix path prefix (dir)
         */
        public static function setDirPrefix($prefix)
        {
                self::$dirPrefix = $prefix;
        }
        /**
         * returns dir prefix
         */
        public static function getDirPrefix()
        {
                return self::$dirPrefix;
        }
 
        /**
         * sets var prefix.
         *
         * @param boolean $activate whether it must be enabled or not
         */
        public static function setVarPrefix($prefix)
        {
                self::$varPrefix = $prefix;
        }
        /**
         * gets var prefix
         */
        public static function getVarPrefix($prefix)
        {
                return self::$varPrefix;
        }
 
 
 
        protected static function _load()
        {
                if (self::$cachedFiles === null)
                {
                        self::$cachedFiles = array();
                        $files = glob(self::$dirPrefix . self::DIR . '*' . EXT);
                        if (empty($files))
                        {
                                $files = array();
                        }
                        $dirLen = strlen(self::$dirPrefix . self::DIR);
                        foreach ($files as $file)
                        {
                                self::$cachedFiles[substr($file, $dirLen, -4)] = filemtime($file); //strip cache/ and .php
                        }
                }
        }
 
        /**
         * starts caching ... Or require cached file if present & valid.
         *
         * @param int|string $lifeTime cachefile's lifetime (integer or strotime() arg). -1 for infinite lifetime
         * @return Cache|false Cache instance if the cache needs to be refreshed, false if the cache is still valid
         */
        public static function start($name, $lifeTime = -1)
        {
                if (self::$actual != null)
                {
                        throw ExceptionManager::nestingCache(self::$actual, $name);
                }
 
                self::_load();
                if (isset(self::$cachedFiles[$name])
                && ($lifeTime == -1 || !date_passed(self::$cachedFiles[$name], $lifeTime)))
                {
                        require self::$dirPrefix . self::DIR . $name . EXT;
                        $prefix = self::_formatPrefix($name);
                        foreach ($vars as $vname)
                        {
                                $GLOBALS[$prefix . $vname] = $$vname;
                        }
                        return false;
                }
                else
                {
                        self::destroy($name); //remove the cache as it's not used anymore.
                        return new self($name);
                }
        }
        /**
         * destroys a cache file
         *
         * @param string $name cache's name
         * @return void
         */
        public static function destroy($name)
        {
                self::_load();
                if (isset(self::$cachedFiles[$name]))
                { //since this will be called even everytime a cache is generated
                        @unlink(self::$dirPrefix . self::DIR . $name . EXT);
                        unset(self::$cachedFiles[$name]);
                }
        }
        /**
         * destroys some cached files by a prefix (auto _ appended)
         *
         * @param string $prefix
         * @todo return number of deleted occurences ?
         */
        public static function destroyPrefix($prefix)
        {
                self::_load();
                foreach (self::$cachedFiles as $name => $lifeTime)
                {
                        if (strpos($name, $prefix . '_') === 0)
                        {
                                @unlink(self::$dirPrefix . self::DIR . $name . EXT);
                                unset(self::$cachedFiles[$name]);
                        }
                }
        }
        /**
         * destroys some cached files by a regexp (nothing prepended / appended)
         *
         * @param string $regexp the regexp
         * @todo return number of deleted occurences ?
         */
        public static function destroyRegexp($regexp)
        {
                self::_load();
                foreach (self::$cachedFiles as $name => $lifeTime)
                {
                        if (preg_match($regexp, $name))
                        {
                                @unlink(self::$dirPrefix . self::DIR . $name . EXT);
                                unset(self::$cachedFiles[$name]);
                        }
                }
        }
 
 
        /**
         * exports variable in eval'able PHP format
         *
         * @param boolean $phpTags=true add PHP tags ?
         */
        protected function _exportVars($phpTags = true)
        {
                if (empty($this->vars))
                        return '';
 
                $code = '';
 
                if ($phpTags)
                        $code .= '<?php ';
                $vars = array_merge($this->vars, array('vars' => array_keys($this->vars)));
 
                foreach ($vars as $name => $value)
                {
                        $code .= sprintf('$%s = %s; ', $name, var_export($value, true));
                }
 
                return $code . ( $phpTags ? ' ?>' : '' );
        }
        /**
         * returns formatted prefix + an underscore if not empty
         *
         * @param string $name cache's name
         */
        protected function _formatPrefix($name)
        {
                if (empty(self::$varPrefix))
                        return '';
                else
                        return str_replace('%%cache%%', $name, self::$varPrefix) . '_';
        }
 
        /**
         * saves cache to it's file + print it on screen. Also, it destructs the class.
         *
         * @param boolean $show show the content just got cached ?
         */
        public function save($show = true)
        {
                file_put_contents(self::$dirPrefix . self::DIR . $this->name . EXT, $this->_exportVars() . ob_get_contents());
                if ($show)
                { //I don't see why not, here it is, the blue ... w8 wut. More seriously > you shouldn't have $show on false.
                        ob_flush();
                }
                $prefix = self::_formatPrefix($this->name);
                foreach ($this->vars as $vname => $value)
                {
                        $GLOBALS[$prefix . $vname] = $value;
                }
                ob_end_clean();
                unset($this);
        }
 
        /**
         * sets a variable
         *
         * @param string $name variable's name
         * @param mixed $value variable's value
         */
        public function set($name, $value)
        {
                $this->vars[$name] = $value;
        }
 
        protected function __construct($name)
        {
                $this->name = $name;
                ob_start(); //php allows nested ouput buffering
        }
        public function __destruct()
        {
                self::$actual = null;
        }
}
?>

 

 

Démonstration

 

Révélation
<?php
define('EXT', strrchr(__FILE__, '.'));
require_once 'Infinite/lib/class/Cache' . EXT;
define('DEBUG', true);
define('DEV', true);
define('ROOT', './');
require_once 'Infinite/lib/functions' . EXT;
 
 
Cache::setDirPrefix('test/');
Cache::setVarPrefix('cached_%%cache%%');
 
switch (rand(0, 20))
{
        case 0:
                Cache::destroy('test_a');
        break;
        case 1:
                Cache::destroyPrefix('test');
        break;
        case 2:
                Cache::destroyRegexp('/^test/');
        break;
}
 
if ($cache = Cache::start('test_a')) {
        echo 'ça aussi ira dans le cache ;). On peut mettre variables + output !';
        $cache->set('random', rand(1, 5));
        $cache->save();
        //$cached_test_random est disponible après save.
        echo '<br />cached : ' . $cached_test_a_random;
} else {
        echo 'variable dispo quand même ?';
        var_dump($cached_test_a_random);
}
?>

 

 

Cordialement,

Hey hey

Link to comment
  • Replies 1
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.