Find attached a patch file for this.
Thanks,
Tony
On 6/7/2007 1:07 PM, Tony Ford wrote:
> Zend_Cache seemed very elegant to me at first, until I tried to make a
> customization.
>
> I have some apps that will be using memcached for objects. Thing is,
> some of my server farms will have multiple sites and networks, all
> using the same pool of memcached servers. Of course all the networks
> will cache similar named objects, like 'acl' for instance. So, to
> avoid namespace trampling, or rather to "create" namespaces, I thought
> it'd be very useful to have cache id prefixes. Now, instead of setting
> keys in memecached just called 'obj_name' they'd be
> 'uniquenetwork_obj_name'. This allows me to have an acl object for
> Network1 (network1_acl) and an acl object for network2 (network2_acl).
>
> I could just go ahead and setup a constant and pass it in along with
> the ids into every load(), save(), remove(), etc calls, but that seems
> like a lot of unnecessary crap. Instead, it makes a lot more sense to
> me to create a new backend option for my "cache id prefix", then have
> each one of those methods concat the prefix on to the front of ids
> automatically just before the real memcache calls are made.
>
> So, I went about this, and its a real mess. First of all, all options
> are hardcoded into the classes and get explicitly checked at object
> instantiation. OK, well, I extended Zend_Cache_Backend_Memcached and
> did this:
>
> public function __construct($options = array())
> {
> // add cache id prefix as an allowed option, default nothing
> $this->_options['cache_id_prefix'] = null;
> // Call parent constructor
> parent::__construct($options);
> }
>
> Then each one of those methods now look basically like this:
>
> public function load($id, $doNotTestCacheValidity = false)
> {
> $id = $this->_options['cache_id_prefix'] . $id;
> parent::load($id, $doNotTestCacheValidity);
> }
>
> Overall, I didn't think that was too big of a deal, but then I
> realized that the backends are hardcoded and checked in Zend_Cache,
> just like the options, so I'd have to do the same thing for that.
> What's worse though, is only the name of the backend is passed in, and
> then class names are created and called with a hardcoded
> 'Zend_Cache_Backend' . $backend. Now I can't even call my class
> something different. Now I'd have to create my class file specifically
> in the /Zend/Cache/Backend directory, and call it something like
> CustomMemcached.
>
> Anyway, overall Zend_Cache is a very nice component with lots of
> options, and I appreciate all of them, its just that its very closed.
> Maybe that was the intention, and if so, maybe you would accept a
> patch file from me to officially add this feature to the memcache
> backend.
>
> Thanks in advance for reading,
> Tony
Index: Memcached.php
===================================================================
--- Memcached.php (revision 264)
+++ Memcached.php (working copy)
@@ -64,6 +64,9 @@
* =====> (boolean) compression :
* true if you want to use on-the-fly compression
*
+ * =====> (string) cache_id_prefix :
+ * prefix for cache ids
+ *
* @var array available options
*/
protected $_options = array(
@@ -72,7 +75,8 @@
'port' => Zend_Cache_Backend_Memcached::DEFAULT_PORT,
'persistent' =>
Zend_Cache_Backend_Memcached::DEFAULT_PERSISTENT
)),
- 'compression' => false
+ 'compression' => false,
+ 'cache_id_prefix' => null
);
/**
@@ -98,6 +102,11 @@
Zend_Cache::throwException('The memcache extension must
be loaded for using this backend !');
}
parent::__construct($options);
+ if (isset($this->_options['cache_id_prefix'])) { //
particular case for this option
+ if (!preg_match('~^[\w]+$~',
$this->_options['cache_id_prefix'])) {
+ Zend_Cache::throwException('Invalid cache_id_prefix
: must use only [a-zA-A0-9_]');
+ }
+ }
if (isset($this->_options['servers'])) {
$value= $this->_options['servers'];
if (isset($value['host'])) {
@@ -131,7 +140,7 @@
if ($doNotTestCacheValidity) {
$this->_log("Zend_Cache_Backend_Memcached::load() :
\$doNotTestCacheValidity=true is unsupported by the Memcached backend");
}
- $tmp = $this->_memcache->get($id);
+ $tmp = $this->_memcache->get($this->_id($id));
if (is_array($tmp)) {
return $tmp[0];
}
@@ -146,7 +155,7 @@
*/
public function test($id)
{
- $tmp = $this->_memcache->get($id);
+ $tmp = $this->_memcache->get($this->_id($id));
if (is_array($tmp)) {
return $tmp[1];
}
@@ -173,7 +182,7 @@
} else {
$flag = 0;
}
- $result = $this->_memcache->set($id, array($data, time()),
$flag, $lifetime);
+ $result = $this->_memcache->set($this->_id($id),
array($data, time()), $flag, $lifetime);
if (count($tags) > 0) {
$this->_log("Zend_Cache_Backend_Memcached::save() : tags
are unsupported by the Memcached backend");
}
@@ -188,7 +197,7 @@
*/
public function remove($id)
{
- return $this->_memcache->delete($id);
+ return $this->_memcache->delete($this->_id($id));
}
/**
@@ -221,5 +230,21 @@
$this->_log("Zend_Cache_Backend_Memcached::clean() :
tags are unsupported by the Memcached backend");
}
}
+
+ /**
+ * Make and return a cache id
+ *
+ * Checks 'cache_id_prefix' and returns new id with prefix or
simply the id if null
+ *
+ * @param string $id cache id
+ * @return string cache id (with or without prefix)
+ */
+ private function _id($id)
+ {
+ if (isset($this->_options['cache_id_prefix'])) {
+ return $this->_options['cache_id_prefix'] . $id; //
return with prefix
+ }
+ return $id; // no prefix, just return the $id passed
+ }
}