WP Cache Helper is a small WordPress library that wraps the object cache and transient APIs with a callback-style
remember() helper, group-flush support for the object cache (which core does not provide),
and per-prefix scoping so multiple consumers on the same site never collide.
Inspired by WP Cache Remember.
- PHP 7.4 or higher
- WordPress 5.0+
- Composer
composer require duckdev/wp-cache-helperThe library autoloads under the DuckDev\Cache\ namespace via PSR-4.
The library is organised as a tiny container wired up by the entry class DuckDev\Cache\Cache. The folder layout
mirrors the namespace:
src/
├── Cache.php # Container + entry point
├── Contracts/
│ ├── ObjectCacheInterface.php
│ └── TransientCacheInterface.php
├── Storage/
│ ├── ObjectCache.php # wp_cache_* wrapper + version-based group flush
│ └── TransientCache.php # (site_)transient wrapper
├── Support/
│ └── KeyPrefixer.php # Shared key + group prefixing
└── Exceptions/
└── CacheException.php
Services receive their collaborators by constructor injection so they can be unit-tested without WordPress in the loop. Construction has no side effects.
Each container instance is scoped to a single prefix. Pass any non-empty string the first time you ask for it; the same prefix returns the same instance on subsequent calls:
$cache = \DuckDev\Cache\Cache::get_instance( 'my_plugin' );You can also instantiate directly (useful for tests where you want to inject custom drivers):
$cache = new \DuckDev\Cache\Cache( 'my_plugin' );Every key, group, and the {prefix}_can_cache toggle filter are namespaced under the supplied prefix.
| Method | Backed by | Purpose |
|---|---|---|
remember() |
Object cache | Read, or compute + cache on miss. |
forget() |
Object cache | Read then delete; return a default on miss. |
persist() |
Transients | Read, or compute + cache on miss. |
cease() |
Transients | Read then delete; return a default on miss. |
flush_group() |
Object cache | Invalidate every entry in a group. |
flush() |
Object cache | Flush the entire object cache. Last resort. |
object_cache() / transient_cache() |
— | Access the underlying driver for finer-grained control. |
Every callback-based helper checks the return value with is_wp_error() and skips caching when one is returned, so a
transient API failure is not memorised.
For debugging, return false from the {prefix}_can_cache filter:
add_filter( 'my_plugin_can_cache', '__return_false' );The second argument is the cache type — 'object' or 'transient' — so the two can be toggled independently.
Retrieve a value from the object cache. If it doesn't exist, run the $callback to generate and cache the value.
$cache = \DuckDev\Cache\Cache::get_instance( 'my_plugin' );
function get_latest_posts() {
global $cache;
return $cache->remember( 'latest_posts', function () {
return new WP_Query( array(
'posts_per_page' => 5,
'orderby' => 'post_date',
'order' => 'desc',
) );
}, 'queries', HOUR_IN_SECONDS );
}Unlike a naive wp_cache_get()-then-fall-back pattern, remember() distinguishes a legitimately cached 0, '',
[], or false from a true miss — the callback only runs when nothing was cached.
Retrieve a value from the object cache then delete it. Returns $default on miss.
$error_message = $cache->forget( 'form_errors', 'flash', false );
if ( $error_message ) {
echo 'An error occurred: ' . esc_html( $error_message );
}Same shape as remember() but backed by the transient API.
$cache->persist( 'latest_tweets_' . $user_id, function () use ( $user_id ) {
return get_latest_tweets_for_user( $user_id );
}, false, 15 * MINUTE_IN_SECONDS );Pass true for the third argument to use site-wide (multisite) transients.
Note: transients use boolean false as the miss sentinel, so a legitimately cached false value is indistinguishable
from a miss. Reach for remember() if you need to cache false.
Transient counterpart to forget().
Invalidate every entry stored under a group, without touching the rest of the object cache. Internally this increments a per-group version sentinel — old entries become unreadable on next access.
Wrapper for wp_cache_flush() with a fallback to $wp_object_cache->flush() when the function is disabled by a
drop-in. Clears every group on the site, so use only as a last resort.
- PHP minimum is now 7.4. PHP 5.6/7.0–7.3 are no longer supported.
- The constructor now requires a prefix:
new Cache( 'my_plugin' ). In 1.x the prefix was a hardcodedduckdev_cacheshared across every consumer. - The
can_cachefilter is now{prefix}_can_cache(e.g.my_plugin_can_cache) rather than the sharedduckdev_cache_can_cache. remember()andforget()now correctly treat a cached0/''/[]/falseas a hit instead of re-running the callback.
The public method surface (remember, forget, persist, cease, flush_group, flush) is otherwise unchanged.
composer install
composer test # PHPUnit
composer phpcs # WordPress Coding Standards- Maintained by Joel James