2013-02-14 20 views
12

Đối với gói của tôi, chúng tôi tận dụng bộ nhớ cache Laravel,Xóa bộ nhớ cache Laravel 4 bằng cách sử dụng mẫu cho khóa?

Mỗi chìa khóa bộ nhớ cache chúng ta tạo ra là tiền tố, vì vậy chúng tôi có được mypackage-config, mypackage-md5ofafilename những lúc tôi cần phải tuôn tất cả các file bộ nhớ cache mà gói của tôi đã tạo ra, vấn đề này? Tôi chỉ biết mẫu phím bộ nhớ cache, tôi không biết toàn bộ khóa!

Vì vậy, tôi cần có cách để đi Cache::forget('mypackage-*') hoặc tương tự, điều này có thể không?

Nếu nó chỉ dành cho hệ thống của tôi, tôi biết tôi đang sử dụng bộ đệm tệp, vì vậy tôi có thể hủy liên kết tệp theo cách thủ công, nhưng vì đó là gói chung tôi không biết phương thức bộ nhớ cache mà người dùng cuối đang sử dụng, tôi chỉ cần biết giao diện (còn gọi là giao diện bộ đệm Laravel).

Trả lời

10

dễ dàng - sử dụng Cache::getMemory()

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

tái bút: không bao giờ bỏ liên kết các tệp 'cache' theo cách thủ công. Bộ nhớ đệm Laravel giữ một bản ghi của tất cả các bản ghi bộ nhớ cache trong một mảng, do đó, nó sẽ được mong đợi các tập tin được ở đó, ngay cả khi bạn 'hủy liên kết' nó.

+1

Chỉ cần lưu ý, với bộ nhớ cache file và Redis, sử dụng Laravel 4, điều này không làm việc. nó nói phương thức getMemory() không được tìm thấy. – Arda

+3

getMemory() có sẵn cho memcache chỉ – Bala

+2

điều này ném một lỗi "" ": {" type ":" ErrorException "," message ":" call_user_func_array() hy vọng tham số 1 là một cuộc gọi lại hợp lệ, lớp 'Illuminate \\ Cache \\ MemcachedStore 'không có phương thức' getMemory '"," file ":" \/Users \/ericcumbee \/Desktop \/phpprojects \/sblitz \/vendor \/laravel \/framework \/src \/Illuminate \ /Cache\/Repository.php "," dòng ": 277}' lỗi cho tôi trong Laravel 4.2 sử dụng memcached – gsueagle2008

14

Một giải pháp khác: miễn là bạn không phải là bằng cách sử dụng tệp hoặc bộ nhớ cache của cơ sở dữ liệu, bạn có thể sử dụng Cache Tags.

Chỉ cần gắn thẻ mọi cache entry với tên gói của bạn:

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

(Bạn cũng có thể sử dụng phương pháp tags với remember, forever, và rememberForever)

Khi đó là thời gian để tuôn ra bộ nhớ cache của bạn các mục nhập của gói chỉ cần thực hiện

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

Lưu ý: Khi bạn cần truy cập các mục trong bộ nhớ cache, bạn vẫn cần phải tham khảo các thẻ. Ví dụ.

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

Bằng cách đó, một mục nhập bộ nhớ cache với phím config có một thẻ khác nhau (ví dụ hisPackage) sẽ không xung đột với bạn.

6

Đây là giải pháp giống như trong câu trả lời được chấp nhận, nhưng được viết lại đặc biệt cho Redis.

Sử dụng KEYS

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

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

Sử dụng 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

việc sử dụng 'KEYS' không được khuyến khích vì nó là lệnh O (N) (tức là bạn có thể kích hoạt DoS bằng cách chạy nó cũng như làm cạn kiệt RAM của máy chủ trong khi chuẩn bị bộ đệm của hồi đáp). Theo v2.8, phương pháp được khuyến nghị là sử dụng lệnh 'SCAN'. –

1

Dưới đây là một ví dụ cụ thể Redis để xóa tất cả các phím dựa trên một tiền tố nhất định. Điều này được dựa trên câu trả lời của Kazik, với một số cơ cấu lại và an toàn hơn.

Lưu ý rằng RedisStore là dưới namespace 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); 
} 
Các vấn đề liên quan