{"id":2376,"date":"2026-11-03T05:00:00","date_gmt":"2026-11-03T05:00:00","guid":{"rendered":"https:\/\/www.woodcentral.com\/-\/peter\/?p=2376"},"modified":"2026-11-03T05:09:34","modified_gmt":"2026-11-03T05:09:34","slug":"using-apcu","status":"publish","type":"post","link":"https:\/\/www.woodcentral.com\/-\/peter\/using-apcu\/","title":{"rendered":"Using APCu"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">APCu is different from OPcache. While OPcache works automatically, APCu requires you to explicitly put data into the cache and retrieve it from your PHP application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Think of it as a small, very fast, shared-memory key-value store for PHP.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can use it to avoid repeatedly performing operations such as database queries, reading JSON files, generating navigation menus, or calculating frequently requested values.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Basic APCu operations<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">APCu has a relatively simple API.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Store a value:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apcu_store('site_title', 'WoodCentral', 3600);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The third argument is the expiration time in seconds. Here, the value expires after one hour.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Retrieve a value:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$title = apcu_fetch('site_title');<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check whether a value exists:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if (apcu_exists('site_title')) {\n    echo 'Cache entry exists';\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Delete a value:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apcu_delete('site_title');<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Clear the entire cache:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apcu_clear_cache();<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Be careful with <code>apcu_clear_cache()<\/code>: it clears the user cache for the applicable APCu environment, not just one application entry.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. A practical example: caching a JSON file<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose your website reads a JSON file containing navigation links or other frequently accessed information.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Without APCu:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$data = json_decode(\n    file_get_contents(__DIR__ . '\/DATA\/links.json'),\n    true\n);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Every request reads and decodes the file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With APCu:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n\n$file = __DIR__ . '\/DATA\/links.json';\n$key  = 'woodcentral_links';\n\n$data = apcu_fetch($key, $success);\n\nif (!$success) {\n    $json = file_get_contents($file);\n    $data = json_decode($json, true);\n\n    if (is_array($data)) {\n        apcu_store($key, $data, 3600);\n    }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now the JSON file is read and decoded only when the cache entry is missing or expires.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Subsequent requests retrieve the already-decoded PHP array from shared memory.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. A reusable caching function<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Rather than repeating the same logic throughout your application, you could create a small helper function.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function wc_cache(string $key, callable $callback, int $ttl = 3600): mixed\n{\n    if (!function_exists('apcu_fetch')) {\n        return $callback();\n    }\n\n    $value = apcu_fetch($key, $success);\n\n    if ($success) {\n        return $value;\n    }\n\n    $value = $callback();\n\n    apcu_store($key, $value, $ttl);\n\n    return $value;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Usage:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$links = wc_cache('links', function () {\n    return json_decode(\n        file_get_contents(__DIR__ . '\/DATA\/links.json'),\n        true\n    );\n});<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Or for a database query:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$categories = wc_cache('categories', function () use ($pdo) {\n    return $pdo-&gt;query(\n        'SELECT * FROM categories ORDER BY name'\n    )-&gt;fetchAll(PDO::FETCH_ASSOC);\n}, 1800);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is sometimes called a cache-aside pattern: the application checks the cache first and retrieves the original data only when necessary.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Cache invalidation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">One important consideration is what happens when the underlying data changes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, if you update <code>links.json<\/code>, the cached version won&#8217;t automatically know about the change.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You have several options:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Expiration: Let the cache entry expire naturally.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apcu_store('links', $data, 300);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Explicit invalidation: Delete the cache entry when the underlying data changes.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apcu_delete('links');<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">File modification time: Automatically invalidate when a file changes.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$file = __DIR__ . '\/DATA\/links.json';\n\n$key = 'links_' . filemtime($file);\n\n$links = wc_cache($key, function () use ($file) {\n    return json_decode(file_get_contents($file), true);\n});<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The last approach is particularly useful for file-based applications.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. APCu versus OPcache<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Feature<\/th><th>APCu<\/th><th>OPcache<\/th><\/tr><tr><td>Stores PHP application data<\/td><td>Yes<\/td><td>No<\/td><\/tr><tr><td>Stores compiled PHP scripts<\/td><td>No<\/td><td>Yes<\/td><\/tr><tr><td>Requires application code<\/td><td>Yes<\/td><td>No<\/td><\/tr><tr><td>Uses shared memory<\/td><td>Yes<\/td><td>Yes<\/td><\/tr><tr><td>Survives PHP\/server restart<\/td><td>No<\/td><td>No<\/td><\/tr><tr><td>Useful for JSON caching<\/td><td>Yes<\/td><td>No<\/td><\/tr><tr><td>Useful for database results<\/td><td>Yes<\/td><td>No<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">They complement one another rather than compete.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. A few things to understand<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">There are some practical limitations:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>APCu is not persistent storage. Never use it as the authoritative copy of important data.<\/li>\n\n\n\n<li>It is generally shared between PHP processes within the same applicable PHP environment, but not across separate servers or isolated PHP environments.<\/li>\n\n\n\n<li>Cache entries can be evicted when memory is exhausted.<\/li>\n\n\n\n<li>APCu is not a replacement for a database.<\/li>\n\n\n\n<li>Cache keys should be namespaced to avoid collisions between applications.<\/li>\n\n\n\n<li>Avoid caching user-specific information under keys shared by all visitors.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You can inspect APCu&#8217;s status using:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>print_r(apcu_cache_info());<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And check its memory usage using:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>print_r(apcu_sma_info());<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">As with OPcache diagnostics, don&#8217;t leave publicly accessible diagnostic scripts on a production website.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-peter-martin wp-block-embed-peter-martin\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"vNai7I0MpH\"><a href=\"https:\/\/www.woodcentral.com\/-\/peter\/memcache-memcached-zend-opcache-and-apcu-understanding-the-differences\/\">Memcache, Memcached, Zend OPcache and APCu: understanding the differences<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"\u201cMemcache, Memcached, Zend OPcache and APCu: understanding the differences\u201d \u2014 Peter Martin\" src=\"https:\/\/www.woodcentral.com\/-\/peter\/memcache-memcached-zend-opcache-and-apcu-understanding-the-differences\/embed\/#?secret=ISFWQhDVWT#?secret=vNai7I0MpH\" data-secret=\"vNai7I0MpH\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>APCu is different from OPcache. While OPcache works automatically, APCu requires you to explicitly put data into the cache and retrieve it from your PHP application. Think of it as a small, very fast, shared-memory key-value store for PHP. You can use it to avoid repeatedly performing operations such as database queries, reading JSON files, &#8230; <a title=\"Using APCu\" class=\"read-more\" href=\"https:\/\/www.woodcentral.com\/-\/peter\/using-apcu\/\" aria-label=\"Read more about Using APCu\">Read more<\/a><\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-2376","post","type-post","status-publish","format-standard","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/www.woodcentral.com\/-\/peter\/wp-json\/wp\/v2\/posts\/2376","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.woodcentral.com\/-\/peter\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.woodcentral.com\/-\/peter\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.woodcentral.com\/-\/peter\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.woodcentral.com\/-\/peter\/wp-json\/wp\/v2\/comments?post=2376"}],"version-history":[{"count":0,"href":"https:\/\/www.woodcentral.com\/-\/peter\/wp-json\/wp\/v2\/posts\/2376\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.woodcentral.com\/-\/peter\/wp-json\/wp\/v2\/media?parent=2376"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.woodcentral.com\/-\/peter\/wp-json\/wp\/v2\/categories?post=2376"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.woodcentral.com\/-\/peter\/wp-json\/wp\/v2\/tags?post=2376"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}