W3 Total Cache + eAccelerator
I was toying around with the W3 Total Cache for its minification and supposed ability to combine CSS and JavaScript and decided to smoosh eAccelerator user cache support into it since the authors have been postponing it for a while. eAccelerator is common enough that it should be supported, at least until the project dies or PHP 6 comes out with integrated APC. It was pretty simple work and it only took about 20 minutes. I borrowed a snippet or two of code from WP Super Cache Plus, what I currently use and am mostly satisfied with.
This is only lightly tested and you have to apply the patch on your own, but it’s a start. (I didn’t modify the documentation, either.)
diff -u -b -B -N -r --exclude CVS -ur w3-total-cache.orig/inc/define.php w3-total-cache/inc/define.php
--- w3-total-cache.orig/inc/define.php 2009-12-07 12:23:12.000000000 -0600
+++ w3-total-cache/inc/define.php 2009-12-10 03:46:29.000000000 -0600
@@ -531,6 +531,10 @@
$engine_name = 'apc';
break;
+ case 'eaccelerator':
+ $engine_name = 'eaccelerator';
+ break;
+
case 'file':
$engine_name = 'disk';
break;
diff -u -b -B -N -r --exclude CVS -ur w3-total-cache.orig/inc/options/general.phtml w3-total-cache/inc/options/general.phtml
--- w3-total-cache.orig/inc/options/general.phtml 2009-12-07 12:23:12.000000000 -0600
+++ w3-total-cache/inc/options/general.phtml 2009-12-10 04:02:47.000000000 -0600
@@ -13,6 +13,7 @@
<input class="button" type="submit" name="flush_all" value="empty all caches" /> at once or
<input class="button" type="submit" name="flush_memcached" value="empty only the memcached cache"<?php if (! $can_empty_memcache): ?> disabled="disabled"<?php endif; ?> /> or
<input class="button" type="submit" name="flush_apc" value="empty only the opcode cache"<?php if (! $can_empty_apc): ?> disabled="disabled"<?php endif; ?> /> or
+ <input class="button" type="submit" name="flush_eaccelerator" value="empty only the opcode cache"<?php if (! $can_empty_eaccelerator): ?> disabled="disabled"<?php endif; ?> /> or
<input class="button" type="submit" name="flush_file" value="empty only the disk cache"<?php if (! $can_empty_file): ?> disabled="disabled"<?php endif; ?> />.
</p>
</form>
@@ -37,6 +38,7 @@
<option value="file"<?php selected($this->_config->get_string('pgcache.engine'), 'file'); ?>>Disk (basic)</option>
<option value="memcached"<?php selected($this->_config->get_string('pgcache.engine'), 'memcached'); ?>>Memcached<?php echo $memcache_engine; ?></option>
<option value="apc"<?php selected($this->_config->get_string('pgcache.engine'), 'apc'); ?><?php if (! $check_apc): ?> disabled="disabled"<?php endif; ?>>Alternative PHP Cache (APC)</option>
+ <option value="eaccelerator"<?php selected($this->_config->get_string('pgcache.engine'), 'eaccelerator'); ?><?php if (! $check_eaccelerator): ?> disabled="disabled"<?php endif; ?>>eAccelerator</option>
</select>
</td>
</tr>
@@ -60,6 +62,7 @@
<option value="file"<?php selected($this->_config->get_string('minify.engine'), 'file'); ?>>Disk</option>
<option value="memcached"<?php selected($this->_config->get_string('minify.engine'), 'memcached'); ?>>Memcached<?php echo $memcache_engine; ?></option>
<option value="apc"<?php selected($this->_config->get_string('minify.engine'), 'apc'); ?><?php if (! $check_apc): ?> disabled="disabled"<?php endif; ?>>Alternative PHP Cache (APC)</option>
+ <option value="eaccelerator"<?php selected($this->_config->get_string('minify.engine'), 'eaccelerator'); ?><?php if (! $check_eaccelerator): ?> disabled="disabled"<?php endif; ?>>eAccelerator</option>
</select>
</td>
</tr>
@@ -83,6 +86,7 @@
<option value="file"<?php selected($this->_config->get_string('dbcache.engine'), 'file'); ?>>Disk</option>
<option value="memcached"<?php selected($this->_config->get_string('dbcache.engine'), 'memcached'); ?>>Memcached<?php echo $memcache_engine; ?></option>
<option value="apc"<?php selected($this->_config->get_string('dbcache.engine'), 'apc'); ?><?php if (! $check_apc): ?> disabled="disabled"<?php endif; ?>>Alternative PHP Cache (APC)</option>
+ <option value="eaccelerator"<?php selected($this->_config->get_string('dbcache.engine'), 'eaccelerator'); ?><?php if (! $check_eaccelerator): ?> disabled="disabled"<?php endif; ?>>eAccelerator</option>
</select>
</td>
</tr>
diff -u -b -B -N -r --exclude CVS -ur w3-total-cache.orig/lib/Minify/Minify/Cache/EAccelerator.php w3-total-cache/lib/Minify/Minify/Cache/EAccelerator.php
--- w3-total-cache.orig/lib/Minify/Minify/Cache/EAccelerator.php 1969-12-31 18:00:00.000000000 -0600
+++ w3-total-cache/lib/Minify/Minify/Cache/EAccelerator.php 2009-12-10 05:43:05.000000000 -0600
@@ -0,0 +1,168 @@
+<?php
+/**
+ * Class Minify_Cache_EAccelerator
+ * @package Minify
+ */
+
+/**
+ * eAccelerator-based cache class for Minify
+ *
+ * <code>
+ * Minify::setCache(new Minify_Cache_EAccelerator());
+ * </code>
+ *
+ * @package Minify
+ * @author Chris Edwards
+ * @author Christopher G. Stach II
+ **/
+class Minify_Cache_EAccelerator {
+
+ /**
+ * Create a Minify_Cache_EAccelerator object, to be passed to
+ * Minify::setCache().
+ *
+ *
+ * @param int $expire seconds until expiration (default = 0
+ * meaning the item will not get an expiration date)
+ *
+ * @return null
+ */
+ public function __construct($expire = 0)
+ {
+ $this->_exp = $expire;
+ }
+
+ /**
+ * Write data to cache.
+ *
+ * @param string $id cache id
+ *
+ * @param string $data
+ *
+ * @return bool success
+ */
+ public function store($id, $data)
+ {
+ return eaccelerator_put($this->_prefix_key($id), "{$_SERVER['REQUEST_TIME']}|{$data}", $this->_exp);
+ }
+
+ /**
+ * Get the size of a cache entry
+ *
+ * @param string $id cache id
+ *
+ * @return int size in bytes
+ */
+ public function getSize($id)
+ {
+ return $this->_fetch($id)
+ ? strlen($this->_data)
+ : false;
+ }
+
+ /**
+ * Does a valid cache entry exist?
+ *
+ * @param string $id cache id
+ *
+ * @param int $srcMtime mtime of the original source file(s)
+ *
+ * @return bool exists
+ */
+ public function isValid($id, $srcMtime)
+ {
+ return ($this->_fetch($id) && ($this->_lm >= $srcMtime));
+ }
+
+ /**
+ * Send the cached content to output
+ *
+ * @param string $id cache id
+ */
+ public function display($id)
+ {
+ echo $this->_fetch($id)
+ ? $this->_data
+ : '';
+ }
+
+ /**
+ * Fetch the cached content
+ *
+ * @param string $id cache id
+ *
+ * @return string
+ */
+ public function fetch($id)
+ {
+ return $this->_fetch($id)
+ ? $this->_data
+ : '';
+ }
+
+ /**
+ * Flushes all data
+ *
+ * Mostly taken from WP Super Cache Plus -cgs
+ *
+ * @return boolean
+ */
+ function flush()
+ {
+ $keylist = eaccelerator_list_keys();
+
+ foreach ($keylist as $key) {
+ /* Trim leading ":" to work around list_keys namespace bug in eAcc.
+ This will still work when bug is fixed */
+ /* This will not be fixed according to eAccelerator Trac ticket
+ * #287 at http://eaccelerator.net/ticket/287 -cgs
+ */
+ $key['name'] = ltrim($key['name'], ':');
+
+ if (strstr($key['name'], $this->_prefix())) {
+ eaccelerator_rm($key['name']);
+ }
+ }
+
+ return true;
+ }
+
+ function _prefix() {
+ global $blog_id;
+
+ return $_SERVER['SERVER_PORT'] . ':' . $blog_id . ':w3tc-minify:';
+ }
+
+ function _prefix_key($id) {
+ return $this->_prefix() . $id;
+ }
+
+ private $_exp = null;
+
+ // cache of most recently fetched id
+ private $_lm = null;
+ private $_data = null;
+ private $_id = null;
+
+ /**
+ * Fetch data and timestamp from eAccelerator, store in instance
+ *
+ * @param string $id
+ *
+ * @return bool success
+ */
+ private function _fetch($id)
+ {
+ if ($this->_id === $id) {
+ return true;
+ }
+ $ret = eaccelerator_get($this->_prefix_key($id));
+ if (false === $ret) {
+ $this->_id = null;
+ return false;
+ }
+ list($this->_lm, $this->_data) = explode('|', $ret, 2);
+ $this->_id = $id;
+ return true;
+ }
+}
diff -u -b -B -N -r --exclude CVS -ur w3-total-cache.orig/lib/W3/Cache/EAccelerator.php w3-total-cache/lib/W3/Cache/EAccelerator.php
--- w3-total-cache.orig/lib/W3/Cache/EAccelerator.php 1969-12-31 18:00:00.000000000 -0600
+++ w3-total-cache/lib/W3/Cache/EAccelerator.php 2009-12-10 05:43:09.000000000 -0600
@@ -0,0 +1,123 @@
+<?php
+
+/**
+ * EAccelerator class
+ */
+
+require_once W3TC_LIB_W3_DIR . '/Cache/Base.php';
+
+/**
+ * Class W3_Cache_EAccelerator
+ * @author unknown
+ * @author Christopher G. Stach II
+ */
+class W3_Cache_EAccelerator extends W3_Cache_Base
+{
+
+ /**
+ * Adds data
+ *
+ * @param string $key
+ * @param mixed $var
+ * @param integer $expire
+ * @return boolean
+ */
+ function add($key, $var, $expire = 0)
+ {
+ if ($this->get($key) === false) {
+ return $this->set($key, $var, $expire);
+ }
+
+ return false;
+ }
+
+ /**
+ * Sets data
+ *
+ * @param string $key
+ * @param mixed $var
+ * @param integer $expire
+ * @return boolean
+ */
+ function set($key, $var, $expire = 0)
+ {
+ return eaccelerator_put($this->_prefix_key($key), serialize($var), $expire);
+ }
+
+ /**
+ * Returns data
+ *
+ * @param string $key
+ * @return mixed
+ */
+ function get($key)
+ {
+ return unserialize(eaccelerator_get($this->_prefix_key($key)));
+ }
+
+ /**
+ * Replaces data
+ *
+ * @param string $key
+ * @param mixed $var
+ * @param integer $expire
+ * @return boolean
+ */
+ function replace($key, $var, $expire = 0)
+ {
+ if ($this->get($key) !== false) {
+ return $this->set($key, $var, $expire);
+ }
+
+ return false;
+ }
+
+ /**
+ * Deletes data
+ *
+ * @param string $key
+ * @return boolean
+ */
+ function delete($key)
+ {
+ return eaccelerator_rm($this->_prefix_key($key));
+ }
+
+ /**
+ * Flushes all data
+ *
+ * Mostly taken from WP Super Cache Plus -cgs
+ *
+ * @return boolean
+ */
+ function flush()
+ {
+ $keylist = eaccelerator_list_keys();
+
+ foreach ($keylist as $key) {
+ /* Trim leading ":" to work around list_keys namespace bug in eAcc.
+ This will still work when bug is fixed */
+ /* This will not be fixed according to eAccelerator Trac ticket
+ * #287 at http://eaccelerator.net/ticket/287 -cgs
+ */
+ $key['name'] = ltrim($key['name'], ':');
+
+ if (strstr($key['name'], $this->_prefix())) {
+ eaccelerator_rm($key['name']);
+ }
+ }
+
+ return true;
+ }
+
+ function _prefix() {
+ global $blog_id;
+
+ return $_SERVER['SERVER_PORT'] . ':' . $blog_id . ':w3tc:';
+ }
+
+ function _prefix_key($id) {
+ return $this->_prefix() . $id;
+ }
+
+}
diff -u -b -B -N -r --exclude CVS -ur w3-total-cache.orig/lib/W3/Cache.php w3-total-cache/lib/W3/Cache.php
--- w3-total-cache.orig/lib/W3/Cache.php 2009-12-07 12:23:12.000000000 -0600
+++ w3-total-cache/lib/W3/Cache.php 2009-12-10 04:04:57.000000000 -0600
@@ -15,6 +15,10 @@
define('W3_CACHE_APC', 'apc');
}
+if (! defined('W3_CACHE_EACCELERATOR')) {
+ define('W3_CACHE_EACCELERATOR', 'eaccelerator');
+}
+
if (! defined('W3_CACHE_FILE')) {
define('W3_CACHE_FILE', 'file');
}
@@ -53,6 +57,11 @@
$instances[$instance_key] = & new W3_Cache_Apc();
break;
+ case W3_CACHE_EACCELERATOR:
+ require_once W3TC_LIB_W3_DIR . '/Cache/EAccelerator.php';
+ $instances[$instance_key] = & new W3_Cache_EAccelerator();
+ break;
+
case W3_CACHE_FILE:
require_once W3TC_LIB_W3_DIR . '/Cache/File.php';
$instances[$instance_key] = & new W3_Cache_File($config);
diff -u -b -B -N -r --exclude CVS -ur w3-total-cache.orig/lib/W3/Config.php w3-total-cache/lib/W3/Config.php
--- w3-total-cache.orig/lib/W3/Config.php 2009-12-07 12:23:12.000000000 -0600
+++ w3-total-cache/lib/W3/Config.php 2009-12-10 04:06:02.000000000 -0600
@@ -132,7 +132,7 @@
'notes.defaults' => 'boolean',
'notes.wp_content_perms' => 'boolean',
'notes.cdn_first_time' => 'boolean',
- 'notes.no_memcached_nor_apc' => 'boolean',
+ 'notes.no_memcached_nor_apc_nor_eaccelerator' => 'boolean',
'notes.php_is_old' => 'boolean',
'notes.theme_changed' => 'boolean',
'notes.wp_upgraded' => 'boolean',
@@ -381,7 +381,7 @@
'notes.defaults' => true,
'notes.wp_content_perms' => true,
'notes.cdn_first_time' => true,
- 'notes.no_memcached_nor_apc' => true,
+ 'notes.no_memcached_nor_apc_nor_eaccelerator' => true,
'notes.php_is_old' => true,
'notes.theme_changed' => false,
'notes.wp_upgraded' => false,
diff -u -b -B -N -r --exclude CVS -ur w3-total-cache.orig/lib/W3/Minify.php w3-total-cache/lib/W3/Minify.php
--- w3-total-cache.orig/lib/W3/Minify.php 2009-12-07 12:23:12.000000000 -0600
+++ w3-total-cache/lib/W3/Minify.php 2009-12-10 04:28:02.000000000 -0600
@@ -172,6 +172,8 @@
return $this->_memcached->flush();
} elseif (is_a($cache, 'Minify_Cache_APC') && function_exists('apc_clear_cache')) {
return apc_clear_cache('user');
+ } elseif (is_a($cache, 'Minify_Cache_EAccelerator') && function_exists('eaccelerator_rm')) {
+ return $cache->flush();
} elseif (is_a($cache, 'Minify_Cache_File')) {
if (! is_dir(W3TC_CACHE_FILE_MINIFY_DIR)) {
$this->log(sprintf('Cache directory %s does not exists', W3TC_CACHE_FILE_MINIFY_DIR));
@@ -369,6 +371,11 @@
$cache[0] = & new Minify_Cache_APC();
break;
+ case 'eaccelerator':
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/Cache/EAccelerator.php';
+ $cache[0] = & new Minify_Cache_EAccelerator();
+ break;
+
default:
require_once W3TC_LIB_MINIFY_DIR . '/Minify/Cache/File.php';
if (! is_dir(W3TC_CACHE_FILE_MINIFY_DIR)) {
diff -u -b -B -N -r --exclude CVS -ur w3-total-cache.orig/lib/W3/Plugin/TotalCache.php w3-total-cache/lib/W3/Plugin/TotalCache.php
--- w3-total-cache.orig/lib/W3/Plugin/TotalCache.php 2009-12-07 12:23:12.000000000 -0600
+++ w3-total-cache/lib/W3/Plugin/TotalCache.php 2009-12-10 04:15:43.000000000 -0600
@@ -296,6 +296,7 @@
if (isset($_REQUEST['flush_all'])) {
$this->flush_memcached();
$this->flush_apc();
+ $this->flush_eaccelerator();
$this->flush_file();
$this->redirect(array(
@@ -326,6 +327,17 @@
}
/**
+ * Flush EAccelerator cache
+ */
+ if (isset($_REQUEST['flush_eaccelerator'])) {
+ $this->flush_eaccelerator();
+
+ $this->redirect(array(
+ 'note' => 'flush_eaccelerator'
+ ));
+ }
+
+ /**
* Flush disk cache
*/
if (isset($_REQUEST['flush_file'])) {
@@ -638,7 +650,8 @@
'config_save' => 'Plugin configuration successfully updated.',
'flush_all' => 'All caches successfully emptied.',
'flush_memcached' => 'Memcached cache(s) successfully emptied.',
- 'flush_apc' => 'Opcode (APC) cache successfully emptied.',
+ 'flush_apc' => 'Opcode cache (APC) successfully emptied.',
+ 'flush_eaccelerator' => 'Opcode cache (eAccelerator) successfully emptied.',
'flush_file' => 'Disk cache successfully emptied.',
'flush_pgcache' => 'Page cache successfull emptied.',
'flush_dbcache' => 'Database cache successfully emptied.',
@@ -930,10 +943,10 @@
}
/**
- * Check for memcached & APC
+ * Check for memcached, APC, & eAccelerator
*/
- if ($this->_config->get_boolean('notes.no_memcached_nor_apc') && ! $this->check_memcache() && ! $this->check_apc()) {
- $this->_notes[] = sprintf('<strong>Memcached</strong> nor an <strong>opcode cache (APC)</strong> appear to be installed correctly. %s', $this->button_hide_note('Hide this message', 'no_memcached_nor_apc'));
+ if ($this->_config->get_boolean('notes.no_memcached_nor_apc_nor_eaccelerator') && ! $this->check_memcache() && ! $this->check_apc() && ! $this->check_eaccelerator()) {
+ $this->_notes[] = sprintf('<strong>Memcached</strong> nor an <strong>opcode cache (APC/eAccelerator)</strong> appear to be installed correctly. %s', $this->button_hide_note('Hide this message', 'no_memcached_nor_apc_nor_eaccelerator'));
}
/**
@@ -992,12 +1005,15 @@
$check_apc = $this->check_apc();
+ $check_eaccelerator = $this->check_eaccelerator();
+
$pgcache_engine = $this->_config->get_string('pgcache.engine');
$dbcache_engine = $this->_config->get_string('dbcache.engine');
$minify_engine = $this->_config->get_string('minify.engine');
$can_empty_memcache = ($pgcache_engine == 'memcached' || $dbcache_engine == 'memcached' || $minify_engine == 'memcached');
$can_empty_apc = $check_apc && ($pgcache_engine == 'apc' || $dbcache_engine == 'apc' || $minify_engine == 'apc');
+ $can_empty_eaccelerator = $check_eaccelerator && ($pgcache_engine == 'eaccelerator' || $dbcache_engine == 'eaccelerator' || $minify_engine == 'eaccelerator');
$can_empty_file = ($pgcache_engine == 'file' || $pgcache_engine == 'file_pgcache' || $dbcache_engine == 'file' || $minify_engine == 'file');
$memcache_engine = class_exists('Memcache') ? ' (via Memcache)' : '';
@@ -2299,6 +2315,15 @@
}
/**
+ * Flush eAccelerator cache
+ * @return void
+ */
+ function flush_eaccelerator()
+ {
+ $this->flush('eaccelerator');
+ }
+
+ /**
* Flush file cache
*
* @return void
@@ -2382,6 +2407,16 @@
}
/**
+ * Checks eAccelerator availability
+ *
+ * @return boolean
+ */
+ function check_eaccelerator()
+ {
+ return function_exists('eaccelerator_put');
+ }
+
+ /**
* Output buffering callback
*
* @param string $buffer
diff -u -b -B -N -r --exclude CVS -ur w3-total-cache.orig/w3-total-cache-config-example.php w3-total-cache/w3-total-cache-config-example.php
--- w3-total-cache.orig/w3-total-cache-config-example.php 2009-12-07 12:23:12.000000000 -0600
+++ w3-total-cache/w3-total-cache-config-example.php 2009-12-10 04:16:04.000000000 -0600
@@ -231,7 +231,7 @@
'notes.defaults' => true,
'notes.wp_content_perms' => true,
'notes.cdn_first_time' => true,
- 'notes.no_memcached_nor_apc' => true,
+ 'notes.no_memcached_nor_apc_nor_eaccelerator' => true,
'notes.php_is_old' => true,
'notes.theme_changed' => false,
'notes.wp_upgraded' => false,

W3 Total Cache + eAccelerator by cum grano salis — nobody likes a clever bastard, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License.

Leave a Reply
You must be logged in to post a comment.