swoole / rfc

Swoole 提案
116 stars 3 forks source link

RFC-1019: Co\Redis 返回值兼容 phpredis #54

Closed matyhtf closed 5 years ago

matyhtf commented 5 years ago

现状

目前Co\Redis::hGetAll直接返回了列表,没有进行 Map 化。与 phpredis 不一致表现不一致。

    $redis = new Swoole\Coroutine\Redis();
    $redis->connect(REDIS_SERVER_HOST, REDIS_SERVER_PORT);
    if (!$redis->exists('hset_1')) {
        assert($redis->hset('hset_1', 'rango', 'han'));
        assert($redis->hset('hset_1', 'jack', 'ma'));
    }
    var_dump($redis->hgetall('hset_1'));
array(4) {
  [0]=>
  string(5) "rango"
  [1]=>
  string(3) "han"
  [2]=>
  string(4) "jack"
  [3]=>
  string(2) "ma"
}

需要在 redis_request完成后,重新组合 PHP 数组。

修改

考虑到已经有很多SwoolePHP框架做了适配,可以新增一个参数,来设置开启兼容模式

$redis->setOptions([
    'compatibility_mode' => true,
]);

启用后,将重组hGetAll返回值为Map格式。返回格式为:

array(2) {
  ["rango"]=>
  string(3) "han"
  ["jack"]=>
  string(2) "ma"
}
twose commented 5 years ago

https://github.com/swoole/swoole-src/issues/1630

    public function handleResult($method, $arguments, $result) {
        if ($method == 'zrank' && $result === null) {
            return false;
        }

        if ($method == 'get' && $result === null) {
            return false;
        }

        if (empty($result)) {
            return $result;
        }

        if ($method == 'hmget') {
            $keys = array_values($arguments[1]);
            $rs = array();
            foreach ($result as $k => $v) {
                $rs[$keys[$k]] = $v;
            }
            $result = $rs;
        } else if (
            $method == 'hgetall' ||
            (in_array($method, array('zrange', 'zrevrange')) && $arguments[3] == true) ||
            (in_array($method, array('zrangebyscore', 'zrevrangebyscore')) && isset($arguments[3]) && $arguments[3]['withscores'])
        ) {
            $keys = array_chunk($result, 2);
            $rs = array();
            foreach ($keys as $v) {
                $rs[$v[0]] = $v[1];
            }
            $result = $rs;
        }

        return $result;
    }