WooCommerce full page cache plugin using Memcached. Allows full control which Products, Categories, Pages should be cleared without flushing the cache.
CREDITS: This plugin is the spiritual successor of WP-FFPC by Peter Molnar.
- Copyright
- License
- Requirements
- Installation
- Settings
- Customization
- Drop-In 'advanced-cache.php'
- NGINX
WooCommerce Memcached Full Page Cache - FPC specialized for WooCommerece via PHP-Memcached.
Copyright (C) 2019 Achim Galeski ( achim@invinciblebrands.com )
Based on: WP-FFPC - A fast, memory based full page cache plugin supporting APC or memcached.
Copyright (C) 2010-2017 Peter Molnar ( hello@petermolnar.eu )
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 3, as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA02110-1301USA
GPL v3 - Please view LICENSE document.
Requried:
- A server running Memcached-Server.
libmemcached
on the Server that runs WordPress/WooCommerce.php-memcached
on the Server that runs WordPress/WooCommerce.PHP 7.x
any version 7 of PHP will do. I have not tested 5.6 yet.
Optional:
SASL
For authentication SASL must be enabled.
- Upload contents of
woocommerce-memcached-full-page-cache.zip
(OR clone this repository) to the/wp-content/plugins/
directory of your wordpress installation. - Enable WordPress caching via adding
define('WP_CACHE', true);
in the filewp-config.php
- Activate the plugin in WordPress
- Check the settings in
WooCommerce
=>Full Page Cache
menu in your Wordpress admin backend. - (!) Save the settings (!) to generate
/wp-content/advanced-cache.php
and activate caching.
As a side note: How to install Memcached
Settings link: yourdomain.xyz/wp-admin/admin.php?page=wc-settings&tab=advanced§ion=full_page_cache
OR
WP Admin => WooCommerce => Settings => Advanced => Full Page Cache
Defaults:
[
'hosts' => '127.0.0.1:11211',
'memcached_binary' => 'yes',
'authpass' => '',
'authuser' => '',
'expire' => '86400',
'browsercache' => '14400',
'prefix_meta' => 'meta-',
'prefix_data' => 'data-',
'charset' => 'utf-8',
'cache_loggedin' => 'yes',
'nocache_cookies' => '',
'nocache_woocommerce_url' => '^/DYNAMIC/|^/DYNAMIC/|^/DYNAMIC/|^/wc\\-api|^/\\?wc\\-api=',
'nocache_url' => '^/wc\\-|^/wp\\-|addons|removed|gdsr|wp_rg|wp_session|wc_session',
'response_header' => 'yes',
'comments_invalidate' => 'yes',
'pingback_header' => '0',
]
hosts
Memcached server list Ip:Port,Ip2:Port2,Ip3:Port
memcached_binary
Enables binary connection mode (faster). However, in some cases this is not possible to use. Unchecked the plugin will fall back to a ASCII mode (slower).
authpass
Stores the password for authentication with all hosts in the list. (!) SASL must be enabled.
authuser
Stores the user for authentication with all hosts in the list. (!) SASL must be enabled.
expire
The expire time of the cached entries in Memcached.
browsercache
Used to determine modified since and when the Browser-cache of a given page should expire.
prefix_meta
The prefix for meta-data keys in memcached. (!) Must be different than the data prefix or entries will be overwritten.
prefix_data
The prefix for page content keys in memcached. (!) Must be different than the meta prefix or entries will be overwritten.
charset
Used to set the charset header when a page is loaded from cache.
cache_loggedin
Enable to load cached pages even for logged in customers/users. (!) Does NOT use cache for Admins.
nocache_cookies
The place to define custom cookies which should prevent caching for users with the cookies provided here.
nocache_woocommerce_url
Contains the regex to exclude WooCommerce API & default dynamic pages like checkout and cart. (!) Generated on save.
nocache_url
Enter your own regex to exclude matches from caching.
response_header
Enable to add the X-Cache response header if cache is loaded.
comments_invalidate
Enable to trigger cache clearing on comment actions.
pingback_header
Enable to preserve the PingBack header for cached pages.
You can use hooks to customize the behaviour of this plugin.
WC_MFPC_PLUGIN_DIR
WC_MFPC_PLUGIN_URL
WC_MFPC_PLUGIN_FILE
-
$wc_mfpc_config_array
Config array loaded via advanced-cache.php
-
$wc_mfpc_memcached
Instance of Memcached::class initiated in wc-mfpc-advanced-cache.php
-
$wcMfpcConfig
Instance of WcMfpcConfig::class initiated in woocommerce-memcached-full-page-cache.php
- wc_mfpc_custom_skip_load_from_cache
- wc_mfpc_custom_skip_caching
- wc_mfpc_custom_cache_content
- wc_mfpc_custom_cache_meta
- wc_mfpc_custom_build_url
- wc_mfpc_custom_build_key
- wc_mfpc_custom_build_keys
- wc_mfpc_custom_expire
- wc_mfpc_custom_advanced_cache_config
-
wc_mfpc_settings_form_top
Lets you add your own fieldset at the beginning of the admin settings form.
-
wc_mfpc_settings_form_bottom
Lets you add your own fieldset at the end of the adming settings form.
-
wc_mfpc_settings_form_memcached_connection
Lets you add your own form fields to the fieldset of the memcached connection settings.
-
wc_mfpc_settings_form_cache
Lets you add your own form fields to the fieldset of the cache settings.
-
wc_mfpc_settings_form_exception
Lets you add your own form fields to the fieldset of the exception settings.
-
wc_mfpc_settings_form_debug
Lets you add your own form fields to the fieldset of the debug settings.
wc_mfpc_custom_skip_load_from_cache
This hook gives you control if a given uri should be processed by the advanced-cache or rather not.
Example #1:
<?php
/**
* Function to customize whether a page is processed by wp-ffpc at all.
*
* @param bool $skip Default: false - return TRUE for skipping
* @param array $config Array with config from advanced-cache.php
* @param string $uri Requested URI string
*
* @return bool $skip
*/
function cust_wc_mfpc_set_skip_load_from_cache($skip = false, $config = [], $uri = '')
{
/*
* If you do somehting like this, don't forget to add this cookie also to your
* cache exclude list in nginx.
*/
if (! empty($_COOKIE[ 'SUPER_SPECIAL_COOKIE' ]) {
$skip = true;
}
return $skip
}
add_filter('wc_mfpc_custom_skip_load_from_cache', 'cust_wc_mfpc_set_skip_load_from_cache')
Example #2:
if (! empty($_COOKIE[ 'SUPER_SPECIAL_COOKIE' ]) {
add_filter('wc_mfpc_custom_skip_load_from_cache', '__return_true');
}
wc_mfpc_custom_skip_caching
This hook gives you control if a given uri should be processed and stored in cache or rather not. The content of the page is already known at this point and can be analysed for consideration.
Example #1:
<?php
/**
* Function to custom skip storing data in cache.
*
* @param bool $skip Set TRUE to skip caching.
* @param string $content The page content.
*
* @return bool $skip
*/
function cust_wc_mfpc_set_skip_caching($skip = false, $content = '')
{
if (! empty(stripos($content, '<div class="skip-me-from-cache">'))) {
$skip = true;
}
return $skip;
}
add_filter('wc_mfpc_custom_skip_caching', 'cust_wc_mfpc_set_skip_caching')
Example #2:
<?php
/*
* Somewhere in your plugin / theme when rendering a special, individual & dynamic page
* which should never be cached.
*/
add_filter('wc_mfpc_custom_skip_caching', '__return_true');
wc_mfpc_custom_cache_content
This hook lets you customize the raw content of a page, before it gets stored in cache.
It can be found here: wc-mfpc-advanced-cache.php
Example:
<?php
/**
* Function to customize the html content of any page.
*
* @param string $cacheContent The content to be stored in cache.
*
* @return string $cacheContent
*/
function cust_wc_mfpc_set_cache_content($cacheContent = '')
{
/*
* Add generation date info, but only to HTML.
*/
if (stripos($cacheContent, '</body>')) {
$insertion = "\n<!-- WC-MFPC cache created date: " . date('c') . " -->\n";
$index = stripos($buffer, '</body>');
$cacheContent = substr_replace($buffer, $insertion, $index, 0);
}
return $cacheContent;
}
add_filter('wc_mfpc_custom_cache_content', 'cust_wc_mfpc_set_cache_content');
wc_mfpc_custom_cache_meta
This hook lets you customize the cache meta data of a page, before it gets stored in cache.
It can be found here: wc-mfpc-advanced-cache.php
Example:
<?php
/**
* Function to customize the cached meta data array of any page.
*
* @param array $cacheMeta The meta data array to be stored in cache.
*
* @return array $cacheMeta
*/
function cust_wc_mfpc_set_cache_meta($cacheMeta = [])
{
/*
* Example:
* Change browsercache expire time for certain page types before storing meta data.
*/
if (is_home() || is_feed) {
$cacheMeta[ 'expire' ] = time() + 1800;
} elseif (is_archive()) {
$cacheMeta[ 'expire' ] = time() + 3600;
} elseif (is_product()) {
$cacheMeta[ 'expire' ] = time() + 7200;
}
return $cacheMeta;
}
add_filter('wc_mfpc_custom_cache_meta', 'cust_wc_mfpc_set_cache_meta');
wc_mfpc_custom_build_url
This hook lets you customize the Url which is used for the Memcached key of the actual viewed page.
Example:
<?php
/**
* Function to customize URL used as Memcached key.
*
* @param string $url The URL determined by the plugins default functionality.
* Default: $url = $scheme . $_SERVER[ 'HTTP_HOST' ] . $_SERVER[ 'REQUEST_URI' ];
* @param string $scheme The Scheme determined by the default functionality.
* Default: 'http://' or 'https://'.
*
* @return string $url
*/
function cust_wc_mfpc_set_build_url($url = '', $scheme = '')
{
return $url . $_SERVER[ 'QUERY_STRING' ];
}
add_filter('wc_mfpc_custom_build_url', 'cust_wc_mfpc_set_build_url', 10, 2);
wc_mfpc_custom_build_key
This hook lets you customize the Key which is used to store in and get values from Memcached.
Example:
<?php
/**
* Function to customize the keys used in Memcached.
*
* @param string $key Cache key string that was set by default.
* Default: $key = $this->config[ 'prefix_' . $type ] . $permalink;
* @param string $permalink Permalink of the cache object in question.
* @param string $type Cache key type to build the prefix.
*
* @return string $key
*/
function cust_wc_mfpc_set_build_key($key = '', $permalink = '', $type = '')
{
if ($type === 'aCustomType') {
$key = 'cust-' . $permalink;
}
return $key;
}
add_filter('wc_mfpc_custom_build_key', 'cust_wc_mfpc_set_build_key', 10, 3);
wc_mfpc_custom_build_keys
This hook lets you customize an array of multiple Keys which are used to store in and get values from Memcached.
Example:
<?php
/**
* Function to customize the list of keys used in Memcached.
*
* @param array $keys Cache keys array which was set by default.
* Default: $key = $this->config[ 'prefix_' . $type ] . $permalink;
* @param array $permalinks Array of Permalinks (as aarray keys) of the cache object in question.
*
* @return array $keys
*/
function cust_wc_mfpc_set_build_keys($keys = [], $permalinks = [])
{
foreach ($permalinks as $permalink => $dummy) {
$keys[ $this->buildKey($permalink, 'cust') ] = true;
}
return $keys;
}
add_filter('wc_mfpc_custom_build_keys', 'cust_wc_mfpc_set_build_keys', 10, 2);
wc_mfpc_custom_expire
This hook lets you customize the Memcached cache expiration time before setting the entry.
Example:
<?php
/**
* Function to customize cache expriration time in seconds.
*
* @param int $expire Lifetime of the cache entry in seconds.
*
* @return int
*/
function cust_wc_mfpc_set_expire($expire = 0)
{
if ($this->config[ 'expire_home' ] !== '' && (is_home() || is_feed())) {
$expire = (int) $this->config[ 'expire_home' ];
} elseif (
$this->config[ 'expire_taxonomy' ] !== ''
&& (is_tax() || is_category() || is_tag() || is_archive())
) {
$expire = (int) $this->config[ 'expire_taxonomy' ];
}
return $expire;
}
add_filter('wc_mfpc_custom_expire', 'cust_wc_mfpc_set_expire');
wc_mfpc_custom_advanced_cache_config
This hook lets you customize the global config array before it gets written into the file wp-content/advanced-cache.php
.
Example:
<?php
/**
* FUnction to customize the Global-Config array before it is written via var_export to the advanced-cache.php file.
*
* @param array $globalConfig Array with the global config array including configs of all blogs.
*
* @return array $globalConfig
*/
function cust_wc_mfpc_set_advanced_cache_config($globalConfig = [])
{
$globalConfig[ 'example_setting' ] = true;
return $globalConfig;
}
add_filter('wc_mfpc_custom_advanced_cache_config', 'cust_wc_mfpc_set_advanced_cache_config');
<?php
/*
Plugin Name: WooCommerce Memcached Full Page Cache (Drop-In: advanced-cache.php)
Plugin URI: https://github.com/hypeventures/woocommerce-memcached-full-page-cache/
Description: WooCommerce full page cache plugin based on Memcached.
Version: 1.0
Author: Achim Galeski <achim@invinciblebrands.com>
License: GPLv3
*/
global $wc_mfpc_config_array;
$wc_mfpc_config_array = array (
'naturalmojo.de.local' =>
array (
'hosts' => '127.0.0.1:11211',
'memcached_binary' => 'yes',
'authpass' => '',
'authuser' => '',
'expire' => '86400',
'browsercache' => '14400',
'prefix_meta' => 'meta-',
'prefix_data' => 'data-',
'charset' => 'utf-8',
'cache_loggedin' => 'yes',
'nocache_cookies' => '',
'nocache_woocommerce_url' => '^/kasse/|^/mein\\-konto/|^/warenkorb/|^/wc\\-api|^/\\?wc\\-api=',
'nocache_url' => '^/wc\\-|^/wp\\-|addons|removed|gdsr|wp_rg|wp_session|wc_session',
'response_header' => 'yes',
'comments_invalidate' => 'yes',
'pingback_header' => '0',
),
);
include_once ('/var/www/html/wp-content/plugins/woocommerce-memcached-full-page-cache/wc-mfpc-advanced-cache.php');
If you are using this plugin in the default settings, it should work very well with nginx.
However, a few tweaks in the nginx site config are needed to optimize page delivery and in best case bypass PHP entirely.
Example:
# In your location block:
...
try_files $uri $uri/ @memcached;
...
# New location blocks for memcached handling:
location @memcached {
default_type text/html;
# Create the key var to get cached page content from Memcached
set $memcached_key data-$scheme://$host$request_uri;
# Create boolean var identifier if Memcached will be used or not.
set $memcached_request 1;
# Set the connection timeout to avoid endless loading times in case Memcached is not available.
memcached_connect_timeout 2s;
# If it is a post request, do not load from cache.
if ($request_method = POST ) {
set $memcached_request 0;
}
# If the URL is internal WordPress, do not load from cache.
if ( $uri ~ "/wp-" ) {
set $memcached_request 0;
}
# If args are set, do not load from cache.
if ( $args ) {
set $memcached_request 0;
}
# If cookie(s) set for logged in users, do not load from cache.
if ($http_cookie ~* "comment_author_|wordpressuser_|wp-postpass_|wordpress_logged_in_" ) {
set $memcached_request 0;
}
# If none of the conditions above where met, load page content from Memcached.
if ( $memcached_request = 1) {
# Define the Memcached Server connection.
memcached_pass 127.0.0.1:11211;
# If Memcached was not reachable or the page is any error page at all, fall back to PHP.
error_page 404 500 502 504 = @rewrites;
}
# If one or more of the conditions above where met, fall back to PHP.
if ( $memcached_request = 0) {
rewrite ^ /index.php last;
}
}
location @rewrites {
add_header X-Cache-Engine "";
rewrite ^ /index.php last;
}
Links:
https://github.com/petermolnar/wp-ffpc/blob/master/wp-ffpc-nginx-sample.conf (english)
https://centminmod.com/nginx_configure_wordpress_ffpc_plugin.html (english)
https://timmehosting.de/high-performance-wordpress-mit-wp-ffpc-memcached-nginx-und-ispconfig (german)