-
Notifications
You must be signed in to change notification settings - Fork 0
Troubleshooting
Symptoms, likely causes, and fixes. If none fit, open an issue with your PHP version, handler and a minimal reproduction.
Cause: you built a handler whose extension isn't loaded (e.g.
Redis without ext-redis, Memcache without
ext-memcached/ext-memcache, or WinCache on PHP 8).
Fix: install/enable the extension, or pre-check and fall back:
$cache = (new Redis())->isSupported()
? Cache::create(Redis::class, [...])
: Cache::create(File::class, ['path' => __DIR__ . '/var/cache']);See Installation.
Cause: the File handler was created without a path (or with
an empty one).
Fix: pass an existing, writable directory:
$dir = __DIR__ . '/var/cache';
is_dir($dir) || mkdir($dir, 0775, true);
$cache = Cache::create(File::class, ['path' => $dir]);Likely causes:
-
The directory isn't writable.
set()returnsfalsewhen the write fails — check the return value and the directory permissions/owner. -
You stored
null. A storednullis a real hit;get()still returnsnull. Usehas()to confirm presence. See Keys, TTL & Values. -
The TTL was
0or negative, which deletes the item.
Cause: the key contains one of {}()/\@: (often : from keys like
user:42) or is empty.
Fix: use ./_, or hash untrusted input:
$key = 'user_' . $id; // or
$key = 'user_' . hash('xxh3', $raw); // for arbitrary inputSee Keys, TTL & Values.
Cause: the cache table doesn't exist or its columns don't match. The PDO
handler returns false (rather than throwing) on query-level errors.
Fix: create the table with the correct schema for your driver — see
PDO Handler → Create the table. To surface the
underlying error while debugging, query the table yourself with PDO in
ERRMODE_EXCEPTION and read the message.
Cause: the DSN, credentials or server are wrong/unreachable. Unlike query errors, a connection failure throws.
Fix: verify the dsn, username, password and that the database is
reachable. Wrap construction in a try/catch to fall back. See
Error Handling.
Cause: clear() deletes rows whose name matches the prefix. With an empty
prefix it clears the whole table; with a prefix it matches prefix% (wildcards in
the prefix are escaped, so cache_ matches cache_* literally).
Fix: set a distinct prefix per application sharing the table.
Cause: clear() flushes the whole Redis database (FLUSHDB) or Memcached
instance (flush()), not just your prefix.
Fix: give the cache its own Redis database index, or a dedicated Memcached
instance. See Redis /
Memcache(d).
Cause: increment() stores without a TTL, so a counter you seeded with a
windowed set($key, 0, $window) loses its window on the first increment — or an
expiry elsewhere reset it.
Fix: manage the window with set() and a rotating key, as in the
soft rate limiter; or use a
native atomic counter for strict needs.
Cause: values are stored via serialize()/unserialize(), so you get an
equal object back, not the same instance. Resources, closures and PDO
handles can't be cached at all.
Fix: compare with ==/assertEquals, not ===/assertSame, and cache plain
data rather than live objects.
Cause: you're analysing code that uses an extension you don't have installed.
Fix: install the extension in your analysis environment, or add stub files
(the package itself ships a small WinCache stub for exactly this — see its
stubs/ directory and phpstan.neon.dist).
Collect your PHP version, the handler and options, and a minimal snippet, then open an issue or ask in Discussions.
initphp/cache · MIT License · part of the InitPHP family
Source · Issues · Discussions · Packagist · Contributing · Security Policy
Getting Started
Core Concepts
Handlers
Guides
Other