2013-02-14 22 views
12

對於我的包,我們利用Laravel緩存,使用鍵的模式從Laravel 4緩存中刪除?

我們創建的每個緩存鍵的前綴,所以我們得到mypackage-configmypackage-md5ofafilename有時我需要刷新,我的包已創建的所有緩存文件,這個問題?我只知道緩存鍵的模式,我不知道整個密鑰!

所以,我需要一種方式去Cache::forget('mypackage-*')或類似的,這是可能的嗎?

如果它只是爲我的系統我知道我使用文件緩存,所以我可以手動取消鏈接文件,但因爲它是一個通用的包,我不知道最終用戶使用什麼緩存方法,我只知道接口(又名Laravel緩存接口)。

回答

10

簡單 - 使用Cache::getMemory()

foreach (Cache::getMemory() as $cacheKey => $cacheValue) 
{ 
    if (strpos($cacheKey, 'mypackage') !== false) 
    { 
     Cache::forget($cacheKey); 
    } 
} 

附:永遠不要手動取消「緩存」文件鏈接。 Laravel緩存會保存數組中所有緩存記錄的記錄,因此即使「取消關聯」它也會期待該文件在那裏。

+1

只是要注意下,用文件緩存和Redis的,使用Laravel 4,這是行不通的。它說沒有找到getMemory()方法。 – Arda 2014-07-10 12:21:50

+3

getMemory()僅適用於memcache – Bala 2014-08-26 01:27:54

+2

這會拋出一個錯誤:{「type」:「ErrorException」,「message」:「call_user_func_array()期望參數1是有效的回調,類'Illuminate \\ Cache \\ MemcachedStore'沒有方法'getMemory'「,」file「:」\/Users \/ericcumbee \/Desktop \/phpprojects \/sblitz \/vendor \/laravel \/framework \/src \/Illuminate \ /Cache\/Repository.php「,」line「:277}'在Laravel 4.2中使用memcached發生錯誤 – gsueagle2008 2014-09-10 20:00:00

14

另一種解決方案:只要你不是使用文件或數據庫緩存,您可以利用的Cache Tags

只需標記你的包名每緩存條目:

Cache::tags('myPackage')->put('config', $config, $minutes); 
Cache::tags('myPackage')->put('md5ofafilename', $md5, $minutes); 

(您也可以使用tagsrememberforeverrememberForever

當它的時間來刷新緩存您包的條目只是做

Cache::tags('myPackage')->flush(); 

注: 當您需要訪問緩存條目時,仍然需要引用標籤。例如。

$myConfig = Cache::tags('myPackage')->get('config'); 

這樣一來,另一個緩存條目鍵config具有不同的標籤(例如hisPackage)將不會與你衝突。

6

下面是與接受的答案相同的解決方案,但專門爲Redis重寫。

使用KEYS

$redis = Cache::getRedis(); 
$keys = $redis->keys("*"); 

foreach ($keys as $key) { 
    if (strpos($key, 'mypackage') !== false) 
    { 
    $redis->del($key); 
    } 
} 

使用SCAN(Redis的> = 2.8.0)

$redis = Cache::getRedis(); 
$cursor = 0; 

while($data = $redis->scan($cursor)) 
{ 
    $cursor = $data[0]; 

    foreach($data[1] as $key) 
    { 
    if (strpos($key, 'mypackage') !== false) 
     { 
     $redis->del($key); 
     } 
    } 
    } 

    if ($cursor == 0) break; 
} 
+1

由於它是一個O(N)命令(即你可以通過運行它來觸發一個DoS以及在準備應答的緩衝區時耗盡你的服務器的RAM),所以非常沮喪地使用'KEYS'。從v2.8開始,推薦的方法是使用'SCAN'命令。 – 2014-12-11 13:48:47

1

這裏是一個Redis的具體例子以清除基於給定前綴的所有密鑰。這是基於Kazik的回答,進行了一些重組並增加了安全性。

注意RedisStore是命名空間Illuminate\Cache\RedisStore

$cacheDriver = Cache::driver(); 
if ($cacheDriver instanceof(RedisStore)) { 
    $cursor = 0; 
    do { 
     $data = $cacheDriver->scan($cursor); 
     $cursor = $data[0]; 
     $cacheEntries = $data[1]; 

     foreach ($cacheEntries as $key) { 
      // This clears based on prefix. Change according to your use case. 
      if (starts_with($key, Cache::getPrefix())) { 
       $redis->del($key); 
      } 
     } 

    } while ($cursor != 0); 
}