【问题标题】:Laravel and redis scanLaravel 和 redis 扫描
【发布时间】:2016-05-30 08:46:25
【问题描述】:

我正在尝试将 redis scan 与 laravel 一起使用。我可以发出一个返回 10 个键的请求,但我希望循环直到返回所有键。我不确定如何用 laravel 做到这一点。目前我有

$test = Redis::scan(0, 'match', '*keypattern*');

我不知道是否有“laravel”的方式来做到这一点。

编辑:

我使用 composer 导入 predis/predis 并让它工作

use Predis\Collection\Iterator;
use Predis;

...

$client = new Predis\Client([
    'scheme' => 'tcp',
    'host'   => 'localhost',
    'port'   => 6379,
]);

foreach (new Iterator\Keyspace($client, '*keypattern*') as $key) {
     $arr[] = $key;
}

但是我想知道laravel的方式

编辑:

单个Redis::scan的var_dump

array(2) {
  [0]=>
  string(4) "23"
  [1]=>
  array(10) {
    [0]=>
    string(19) "key17"
    [1]=>
    string(19) "key72"
    [2]=>
    string(76) "key11"
    [3]=>
    string(19) "key73"
    [4]=>
    string(19) "key63"
    [5]=>
    string(19) "key87"
    [6]=>
    string(19) "key70"
    [7]=>
    string(19) "key65"
    [8]=>
    string(19) "key82"
    [9]=>
    string(19) "key43"
  }
}

【问题讨论】:

  • Laravel 在后台使用 Predis (github.com/laravel/framework/blob/5.2/src/Illuminate/Redis/…)。你试过循环调用scan吗?
  • @martinczerwi 我不知道该怎么做...
  • 简短的问题,因为我目前无法重建。第一个代码示例中的$test 应该包含一个用于迭代的游标(就像本机 Redis 调用一样)。这是您在下次调用扫描时使用的内容。你能粘贴$test的var_dump吗?

标签: laravel laravel-5 redis laravel-5.2


【解决方案1】:

谢谢@martinczerwi 这是一个非递归版本:

function scanAllForMatch($pattern)
{
    $cursor = 0;
    do {
        list($cursor, $keys) = Redis::scan($cursor, 'match', $pattern);
        foreach ($keys as $key) {
            yield $key;
        }
    } while ($cursor);
}

【讨论】:

    【解决方案2】:

    由于 Redis 外观将命令直接传递给 Predis(或者您可能会说是 Redis 本身),这与 Redis 文档 (http://redis.io/commands/scan) 密切相关。您可以使用光标(第一个数组条目)进行后续调用以迭代直到光标为零。

    我采用了一种递归方法来扫描所有条目:

    function scanAllForMatch ($pattern, $cursor=null, $allResults=array()) {
    
        // Zero means full iteration
        if ($cursor==="0") {
            return $allResults;
        }
    
        // No $cursor means init
        if ($cursor===null) {
            $cursor = "0";
        }
    
        // The call
        $result = Redis::scan($cursor, 'match', $pattern);
    
        // Append results to array
        $allResults = array_merge($allResults, $result[1]);
    
        // Recursive call until cursor is 0
        return scanAllForMatch($pattern, $result[0], $allResults);
    }
    

    请注意,如果您在类中使用它,您可能需要在递归之前添加$this(将是return $this->scanAllForMatch(...)

    你会这样称呼它:

    // Don't pass a cursor yourself!
    $allResults = scanAllForMatch('*keypattern*');
    

    【讨论】:

    • 谢谢,小修后效果很好。感谢您提醒丢失和重复的键。
    • 太好了,也感谢您的编辑。我首先使用了array_push,它以第一个参数作为参考,但结果不是我想要的;)
    • 必须将 ($cursor==="0") 更改为 ($cursor==0) 才能正常工作
    猜你喜欢
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    • 1970-01-01
    • 2015-07-27
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    相关资源
    最近更新 更多