Skip to content

Commit

Permalink
v.1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikos M committed Oct 24, 2018
1 parent 16d20ae commit f80adb9
Show file tree
Hide file tree
Showing 17 changed files with 735 additions and 306 deletions.
36 changes: 19 additions & 17 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#UNICACHE
# UNICACHE

__An agnostic universal caching framework for PHP, Node/JS, Python__
__An agnostic, caching framework for PHP, Node/JS, Python__

python,node implementations in progress..


###Contents
### Contents

* [How to use](#how-to-use)
* [Types of Caching Supported](#types-of-caching-supported)
Expand All @@ -14,8 +14,9 @@ python,node implementations in progress..
* [Notes](#notes)


###How to Use
This is a caching framework for applications that is universal and agnostic and total.
### How to Use

This is a caching framework for applications that is agnostic and total.

This means that one can use it easily in her web applications that use any given framework or not use any framework at all.

Expand All @@ -26,30 +27,31 @@ The framework is configured by a config file which easily gets together all para
A demo is included with the package. One simply adds an include directive and bang you have the most advanced caching.


###Types of Caching Supported
### Types of Caching Supported

* File-based caching
* APC
* APCU
* XCache
* Memcached
* it is very easy to extend to other methods as well (eg xCache).
* Redis
* it is very easy to extend to other methods as well.


###TODO
### TODO

^ add node/js, python implementations
* add support for Redis
* add support for xCache
* add support for Redis [DONE]
* add support for xCache [DONE]


###ChangeLog
### ChangeLog


###Notes
part of the code is based on code from: http://www.rooftopsolutions.nl/blog/107
### Notes

Part of the code is based on code from: http://www.rooftopsolutions.nl/blog/107

*UNICACHE* is also part of PHP classes http://www.phpclasses.org/package/7530-PHP-Cache-data-in-files-APC-or-Memcached.html

*UNICACHE* is also part of PHP classes http://www.phpclasses.org/package/7530-PHP-Cache-data-in-files-APC-or-Memcached.html

*URL* [Nikos Web Development](http://nikos-web-development.netai.net/ "Nikos Web Development")
*URL* [UNICACHE blog post](http://nikos-web-development.netai.net/blog/unicache-universal-caching-framework-for-php/ "UNICACHE blog post")
*URL* [WorkingClassCode](http://workingclasscode.uphero.com/ "Working Class Code")
68 changes: 68 additions & 0 deletions src/php/Unicache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php
/**
* Unicache
* An agnostic caching framework for PHP, Python, Node/JS
*
* @version: 1.0.0
* https://github.com/foo123/Unicache
*
**/

if ( !class_exists('UNICACHE_Cache', false) )
{
abstract class UNICACHE_Cache
{
abstract function get( $key );
abstract function put( $key, $data, $ttl );
abstract function remove( $key );
}

class UNICACHE_Factory
{
const VERSION = '1.0.0';
public static function getCache( $config )
{
$backend = strtoupper($config['cacheType']);
$cache = null;
switch( $backend )
{
case 'FILE':
require_once(dirname(__FILE__).'/adapters/UnicacheFile.php');
$cache = new UNICACHE_FileCache();
$cache->setCacheDir( $config['FILE']['cacheDir'] );
break;
case 'APC':
require_once(dirname(__FILE__).'/adapters/UnicacheApc.php');
$cache = new UNICACHE_APCCache();
break;
case 'APCU':
require_once(dirname(__FILE__).'/adapters/UnicacheApcu.php');
$cache = new UNICACHE_APCUCache();
break;
case 'XCACHE':
require_once(dirname(__FILE__).'/adapters/UnicacheXCache.php');
$cache = new UNICACHE_XCache();
break;
case 'MEMCACHED':
require_once(dirname(__FILE__).'/adapters/UnicacheMemcached.php');
$cache = new UNICACHE_MemcachedCache();
foreach ((array)$config['MEMCACHED']['servers'] as $srv)
{
$cache->addServer( $srv['host'], $srv['port'], $srv['weight'] );
}
break;
case 'REDIS':
require_once(dirname(__FILE__).'/adapters/UnicacheRedis.php');
$cache = new UNICACHE_RedisCache();
$cache->server( $config['REDIS']['server']['host'], $config['REDIS']['server']['port'] );
break;
default:
// default in-memory cache
require_once(dirname(__FILE__).'/adapters/UnicacheMemory.php');
$cache = new UNICACHE_MemoryCache();
break;
}
return $cache;
}
}
}
20 changes: 20 additions & 0 deletions src/php/adapters/UnicacheApc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

class UNICACHE_APCCache extends UNICACHE_Cache
{
public function get( $key )
{
return apc_fetch( $key );
}

public function put( $key, $data, $ttl )
{

return apc_store( $key, $data, $ttl );
}

public function remove( $key )
{
return apc_delete( $key );
}
}
21 changes: 21 additions & 0 deletions src/php/adapters/UnicacheApcu.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

class UNICACHE_APCUCache extends UNICACHE_Cache
{
public function get( $key )
{
$data = apcu_fetch( $key, $success );
return $success ? $data : false
}

public function put( $key, $data, $ttl )
{

return apcu_store( $key, $data, $ttl );
}

public function remove( $key )
{
return apcu_delete( $key );
}
}
76 changes: 76 additions & 0 deletions src/php/adapters/UnicacheFile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

class UNICACHE_FileCache extends UNICACHE_Cache
{
private $cachedir = '';

public function put( $key, $data, $ttl )
{
// Opening the file in read/write mode
$ch = fopen($this->getFileName($key),'a+');
if (!$ch)
throw new \Exception('UNICACHE: Could not save to cache');

flock($ch,LOCK_EX); // exclusive lock, will get released when the file is closed
fseek($ch,0); // go to the start of the file
// truncate the file
ftruncate($ch,0);

// Serializing along with the TTL
$data = serialize(array(time()+(int)$ttl,$data));
if (false === fwrite($ch,$data))
throw new \Exception('UNICACHE: Could not save to cache');
fclose($ch);
}

public function get( $key )
{
$filename = $this->getFileName($key);
if (!file_exists($filename)) return false;
$ch = fopen($filename,'r');

if (!$ch) return false;

// Getting a shared lock
flock($ch,LOCK_SH);

$data = file_get_contents($filename);
fclose($ch);

$data = @unserialize($data);
if (!$data)
{
unlink($filename);
return false;
}

if (time() > $data[0])
{
// Unlinking when the file was expired
unlink($filename);
return false;
}
return $data[1];
}

public function remove( $key )
{
$filename = $this->getFileName($key);
if (file_exists($filename))
return unlink($filename);
else
return false;
}

public function setCacheDir( $dir )
{
$this->cachedir = rtrim((string)$dir, '/\\');
if ( !(file_exists($this->cachedir) && is_dir($this->cachedir)) )
@mkdir($this->cachedir);
}

protected function getFileName( $key )
{
return $this->cachedir . DIRECTORY_SEPARATOR . md5($key);
}
}
35 changes: 35 additions & 0 deletions src/php/adapters/UnicacheMemcached.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

class UNICACHE_MemcachedCache extends UNICACHE_Cache
{

// Memcache object
private $connection;

public function __construct()
{
$this->connection = new MemCache( );
}

public function put( $key, $data, $ttl )
{
return $this->connection->set( $key, $data, 0, $ttl);
}

public function get( $key )
{
return $this->connection->get( $key );
}

public function remove( $key )
{
return $this->connection->delete( $key );
}

public function addServer( $host, $port=11211, $weight=10 )
{
$this->connection->addServer( $host, $port, true, $weight );
return $this;
}

}
30 changes: 30 additions & 0 deletions src/php/adapters/UnicacheMemory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

class UNICACHE_MemoryCache extends UNICACHE_Cache
{
private $_cache = array();

public function put( $key, $data, $ttl )
{
$this->_cache[$key] = array(time()+(int)$ttl,$data);
}

public function get( $key )
{

if ( !isset($this->_cache[$key]) ) return false;

$data = $this->_cache[$key];
if ( !$data ) return false;

if ( time() > $data[0] ) return false;
return $data[1];
}

public function remove( $key )
{
if ( !isset($this->_cache[$key]) ) return false;
unset($this->_cache[$key]);
return true;
}
}
41 changes: 41 additions & 0 deletions src/php/adapters/UnicacheRedis.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php
require_once(dirname(__FILE__).'/drivers/redis.php');

class UNICACHE_RedisCache extends UNICACHE_Cache
{

// Lightweight Redis client
private $redis;

public function put( $key, $data, $ttl )
{
$data = serialize(array(time()+(int)$ttl, $data));
return $this->redis->cmd('SET', $key, $data)->cmd('EXPIRE', $key, (int)$ttl)->set();
}

public function get( $key )
{
$data = $this->redis->cmd('GET', $key)->get();
if ( !$data ) return false;
$data = @unserialize($data);
if ( !$data ) return false;
if ( time() > $data[0] )
{
$this->redis->cmd('DEL', $key)->set();
return false;
}
return $data[1];
}

public function remove( $key )
{
return $this->redis->cmd('DEL', $key)->set();
}

public function server( $host, $port=6379 )
{
$this->redis = new redis_cli( $host, $port );
return $this;
}

}
21 changes: 21 additions & 0 deletions src/php/adapters/UnicacheXCache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

class UNICACHE_XCache extends UNICACHE_Cache
{
public function get( $key )
{
$data = xcache_get( $key );
return null !== $data ? $data : false
}

public function put( $key, $data, $ttl )
{

return xcache_set( $key, $data, $ttl );
}

public function remove( $key )
{
return xcache_unset( $key );
}
}
Loading

0 comments on commit f80adb9

Please sign in to comment.