如何通过 Laravel 5 中的键获取所有缓存项的列表?

How to get list of all cached items by key in Laravel 5?

laravel中的Cacheclass有get('itemKey')等方法从缓存中取回item,记得('itemKey',['myData1', 'myData2']) 将项目保存在缓存中。

还有一种检查缓存中是否存在项目的方法:Cache::has('myKey');

有什么方法(当使用基于文件的缓存驱动程序时)获取缓存中所有项目的列表?

例如,可以命名为 "Cache::all()" 的东西 return:

[
    'itemKey' => [
        'myData1',
        'myData2'
   ],
   'myKey' => 'foo'
]

我能想到的唯一方法是使用 Cache::has() 方法遍历所有可能的键名。即 aaa、aab、aac、aad...当然,这不是解决方案。

我在文档或 API 中看不到任何描述此类功能的内容,但我认为相信它必须存在是不合理的。

无法使用 Cache 门面来做到这一点。它的界面代表了所有底层存储提供的功能,一些存储不允许列出所有键。

如果您正在使用 FileCache,您可以尝试通过直接与底层存储交互来实现。它不提供您需要的方法,因此您需要遍历缓存目录。由于可能需要大量磁盘 I/O,因此效率不会太高。

为了访问存储,您需要执行

$storage = Cache::getStore(); // will return instance of FileStore
$filesystem = $storage->getFilesystem(); // will return instance of Filesystem

$keys = [];
foreach ($filesystem->allFiles('') as $file1) {
  foreach ($filesystem->allFiles($file1) as $file2) {
    $keys = array_merge($keys, $filesystem->allFiles($file1 . '/' . $file2));
  }
}

旧的答案在 Laravel 5.2 中对我不起作用,所以我使用了这个解决方案:

    $storage = \Cache::getStore(); // will return instance of FileStore
    $filesystem = $storage->getFilesystem(); // will return instance of Filesystem
    $dir = (\Cache::getDirectory());
    $keys = [];
    foreach ($filesystem->allFiles($dir) as $file1) {

        if (is_dir($file1->getPath())) {

            foreach ($filesystem->allFiles($file1->getPath()) as $file2) {
                $keys = array_merge($keys, [$file2->getRealpath() => unserialize(substr(\File::get($file2->getRealpath()), 10))]);
            }
        }
        else {

        }
    }

'yourKeyGoesHere'中,您可以插入一个与*相同的字符串,或者直接插入完全相同的键。

 $redis = Cache::getRedis();
 $a_keys = $redis->keys("*yourKeyGoesHere*");
 foreach ($a_keys as $key){
    //Your Action ...
    //For example forget key
    $redis->del($key);
 }

对于 Memcached,您可以这样做:

cache()->getMemcached()->getAllKeys()
  1. 得到Illuminate\Cache\CacheManager
  2. 获取Memcachedhttp://php.net/manual/de/class.memcached.php
  3. getAllKeys(): http://php.net/manual/de/memcached.getallkeys.php

这为您提供了一组可以通过的键。

\config\database.php中为缓存创建一个redis存储

   // store cache in their own redis store ...
    'cache-connection' => [
        'host'               => ...,
        'password'           => ...,
        'port'               => env('REDIS_PORT', 6379),
        'database'           => 2,
        'read_write_timeout' => 60,
        'timeout'            => 6.0,
    ],

\config\cache.php中使用这个redis数据库

'stores' => [
   ...
   'redis' => [
        'driver'     => 'redis',
        'connection' => 'cache-connection',
    ],
],

现在您可以使用 Redis class 检查缓存中的内容

$a = Redis::connection('cache-connection')->keys('*');
\Log::debug($a);

我知道这是一个老问题,但前几天我 运行 研究过这个问题,但在任何地方都找不到文件存储系统的解决方案。

我的用例是我希望能够根据句号分隔组的命名约定进行删除。例如 cache()->forget('foo') 不会删除密钥 foo.bar.

它的工作方式是它保留一个 json 编码数组,其中包含您添加到文件存储的所有键,然后当您想要删除它时,它会循环遍历,如果匹配则将其删除。这可能对您也有用,但如果不是,您的用例可以利用现在也可以使用的 cache()->getKeys() 方法。

要遵循的步骤:

在您的 AppServiceProvider.php register 方法中添加以下内容:

use Illuminate\Support\Facades\Cache;
use App\Extensions\FileStore;
...
$this->app->booting(function () {
    Cache::extend('file', function ($app) {
        return Cache::repository(new FileStore($app['files'], config('cache.stores.file.path'), null));
    });
});

然后在 app 中创建一个名为 Extensions 的新目录。在名为 FileStore.php 的新 Extensions 目录中添加一个新文件,内容如下:

<?php

namespace App\Extensions;

class FileStore extends \Illuminate\Cache\FileStore
{
    /**
     * Get path for our keys store
     * @return string
     */
    private function keysPath()
    {
        return storage_path(implode(DIRECTORY_SEPARATOR, ['framework','cache','keys.json']));
    }

    /**
     * Get all keys from our store
     * @return array
     */
    public function getKeys()
    {
        if (!file_exists($this->keysPath())) {
            return [];
        }

        return json_decode(file_get_contents($this->keysPath()), true) ?? [];
    }

    /**
     * Save all keys to file
     * @param  array $keys
     * @return bool
     */
    private function saveKeys($keys)
    {
        return file_put_contents($this->keysPath(), json_encode($keys)) !== false;
    }

    /**
     * Store a key in our store
     * @param string $key [description]
     */
    private function addKey($key)
    {
        $keys = $this->getKeys();

        // Don't add duplicate keys into our store
        if (!in_array($key, $keys)) {
            $keys[] = $key;
        }

        $this->saveKeys($keys);
    }

    // -------------------------------------------------------------------------
    // LARAVEL METHODS
    // -------------------------------------------------------------------------

    /**
     * Store an item in the cache for a given number of seconds.
     *
     * @param  string  $key
     * @param  mixed  $value
     * @param  int  $seconds
     * @return bool
     */
    public function put($key, $value, $seconds)
    {
        $this->addKey($key);
        return parent::put($key, $value, $seconds);
    }

    /**
     * Remove an item from the cache.
     *
     * @param  string  $key
     * @return bool
     */
    public function forget($forgetKey, $seperator = '.')
    {
        // Get all stored keys
        $storedKeys = $this->getKeys();

        // This value will be returned as true if we match at least 1 key
        $keyFound = false;

        foreach ($storedKeys as $i => $storedKey) {
            // Only proceed if stored key starts with OR matches forget key
            if (!str_starts_with($storedKey, $forgetKey.$seperator) && $storedKey != $forgetKey) {
                continue;
            }

            // Set to return true after all processing
            $keyFound = true;

            // Remove key from our records
            unset($storedKeys[$i]);
            
            // Remove key from the framework
            parent::forget($storedKey);
        }

        // Update our key list
        $this->saveKeys($storedKeys);

        // Return true if at least 1 key was found
        return $keyFound;
    }
    
    /**
     * Remove all items from the cache.
     *
     * @return bool
     */
    public function flush()
    {
        $this->saveKeys([]);
        return parent::flush();
    }
}

步骤 1

// Add Namespace
use Illuminate\Support\Facades\Redis;

步骤 2

// Get All Available Keys
$cacheKeys = Redis::connection('cache')->keys('*');

步骤 3

// Laravel DDD
ddd($cacheKeys);

// PHP Variable Dump
var_dump($cacheKeys);