【问题标题】:How to get list of all cached items by key in Laravel 5?如何在 Laravel 5 中按键获取所有缓存项目的列表?
【发布时间】:2015-10-25 18:56:56
【问题描述】:

laravel 中的 Cache 类有 get('itemKey') 等方法从缓存中检索项目,以及 remember('itemKey', ['myData1', 'myData2']) 等方法将项目保存在缓存中。

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

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

例如,可能被命名为“Cache::all()”之类的东西会返回:

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

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

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

【问题讨论】:

  • 你使用什么缓存后端?雷迪斯?内存缓存?还是?
  • 文件缓存。我读过有一个类似于我为 Memcached 描述的功能,并且可以选择使用标签。但我需要使用文件作为它的大量数据。

标签: php laravel caching laravel-5 key


【解决方案1】:

旧的答案在 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 {

        }
    }

【讨论】:

  • 在我的服务器上,我发现它们不在另一个目录中,因此需要 else {} $keys = array_merge($keys, [$file1->getRealpath() => unserialize(substr(\文件::get($file1->getRealpath()), 10))]);
  • 这是在 Laravel 5.3 上的,因为 jedrzej.kurylo 不起作用,但是这样做了
【解决方案2】:

使用 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));
  }
}

【讨论】:

【解决方案3】:

'yourKeyGoesHere' 中,您可以插入与 * 相同的字符串或直接插入确切的键。

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

【讨论】:

  • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
  • 我认为可以使用 Redis,但是...请解释一下? yourKeyGoesHere 是什么?
  • $redis->keys('*');会给你所有的钥匙
  • Cache::getRedis() 不起作用(Laravel 8),Cache::driver() 起作用,但你得到一个 Illuminate\Cache\Repository 的实例,它似乎没有提供获取整个缓存内容的方法。
【解决方案4】:

对于 Memcached,您可以这样做:

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

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

【讨论】:

    【解决方案5】:

    \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 类检查缓存中的内容

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

    【讨论】:

    • 我尝试遵循这个建议,但在我从键中获取值的部分卡住了:question here
    【解决方案6】:

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

    我的用例是我希望能够根据句号分隔组的命名约定来删除。例如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();
        }
    }
    

    【讨论】:

      【解决方案7】:

      第 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);
      

      【讨论】:

      • 感谢您的贡献,但这个答案是already given,不需要重复。
      猜你喜欢
      • 1970-01-01
      • 2021-01-13
      • 2016-04-12
      • 1970-01-01
      • 2018-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多