Yii Cache::get() cannot distinguish cached false from missing key
0 reputation · 24 Jan 2022, 20:38 UTC
0 reputation · 24 Jan 2022, 20:38 UTC
34775 reputation · 25 Jan 2022, 00:54 UTC
In Yii 2, call Cache::has() before Cache::get() to tell a cached false from a missing key. If you are on Yii 1.x, or want a single-call pattern that works across adapters, pass a unique sentinel as the default value to get() instead.
false is ambiguousThe base Cache::get() contract returns false both when a key is absent and when the stored value is boolean false. This applies to FileCache, DbCache, MemCache, and RedisCache because the ambiguity is in the base method, not the adapter. getOrSet() avoids unnecessary recomputation on a miss, but it still returns false and does not reveal whether the value came from the cache.
if ($cache->has('feature_flag')) {
$value = $cache->get('feature_flag');
} else {
$value = computeFeatureFlag();
$cache->set('feature_flag', $value);
}
A key can expire between has() and get() under heavy concurrency; if that matters, use the sentinel pattern below.
define('CACHE_MISS', 'APP_CACHE_MISS_SENTINEL');
$raw = $cache->get('feature_flag', CACHE_MISS);
if ($raw === CACHE_MISS) {
$value = computeFeatureFlag();
$cache->set('feature_flag', $value);
} else {
$value = $raw; // may legitimately be false, null, 0, or ''
}
Yii 1.x does not expose Cache::has() consistently, so this sentinel default is the portable workaround. The sentinel must be a value your application never stores under the same key.
$cache->set('test', false);$cache->has('test') is true, then $cache->get('test') returns false.$cache->delete('test');$cache->has('test') is false, and $cache->get('test', CACHE_MISS) returns CACHE_MISS.null, 0, and an empty string to confirm the sentinel does not collide.Missing diagnostic detail: which Yii version are you using? Cache::has() is the straightforward answer for Yii 2; Yii 1.x requires the sentinel workaround.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.