I have a class for interacting with a memcache server. I have different functions for inserting, deleting and retrieving data. Originally each function made a call to memcache_connect()
, however that was unnecessary, e.g.:
mc->insert()
mc->get()
mc->delete()
would make three memcache connections. I worked around this by creating a construct for the class:
function __construct() {
$this->mem = memcache_connect( ... );
}
and then using $this->mem
wherever the resource was needed, so each of the three functions use the same memcache_connect
resource.
This is alright, however if I call the class inside other classes, e.g.:
class abc
{
function __construct() {
$this->mc = new cache_class;
}
}
class def
{
function __construct() {
$this->mc = new cache_class;
}
}
then it is still making two memcache_connect
calls, when it only needs one.
I can do this with globals but I would prefer not to use them if I don't have to.
Example globals implementation:
$resource = memcache_connect( ... );
class cache_class
{
function insert() {
global $resource;
memcache_set( $resource , ... );
}
function get() {
global $resource;
return memcache_get( $resource , ... );
}
}
Then no matter how many times the class is called there will only be one call to memcache_connect
.
Is there a way to do this or should I just use globals?
I would code another class using singleton pattern for getting the only instance of memcache. Like this -
class MemCache
{
private static $instance = false;
private function __construct() {}
public static function getInstance()
{
if(self::$instance === false)
{
self::$instance = memcache_connect();
}
return self::$instance;
}
}
and usage -
$mc = MemCache::getInstance();
memcache_get($mc, ...)
...
Pass in the MC instance:
class abc
{
function __construct($mc) {
$this->mc = $mc;
}
}
class def
{
function __construct($mc) {
$this->mc = $mc;
}
}
$mc = new cache_class;
$abc = new abc($mc);
etc.
I think you're looking for static properties here.
class mc {
private static $instance;
public static function getInstance() {
if (self::$instance== null) {
self::$instance= new self;
}
return self::$instance;
}
private function __construct() {
$this->mem = memcache_connect(...);
}
}
This implements a basic singleton pattern. Instead of constructing the object call mc::getInstance()
. Have a look at singletons.
You should use dependency injection. The singleton pattern and static constructs are considered bad practice because they essentially are globals (and for good reason -- they cement you to using whatever class you instantiate as opposed to some other).
Here is something like what you should do in order to have easy maintenance.
class MemCache {
protected $memcache;
public function __construct(){
$this->memcache = memcache_connect();
}
}
class Client {
protected $MemCache;
public function __construct( MemCache $MemCache ){
$this->MemCache = $MemCache;
}
public function getMemCache(){
return $this->MemCache;
}
}
$MemCache = new MemCache();
$Client = new Client($MemCache);
$MemCache1 = $Client->getMemCache();
// $MemCache and $MemCache1 are the same object.
// memcache_connect() has not been called more than once.