在Redis中将JSON作为字符串存储时转义特殊字符


Escaping special characters while storing JSON as string in Redis

我试图通过PHP在Redis中存储JSON数据,但通过Redis -cli命令行客户端进行测试。

在两个客户端中,我似乎无法在不转义的情况下存储JSON。

redis 127.0.0.1:6379> set test1 {"array":[1,2,3],"number":123,"object":{"a":"b","c":"d","e":"f"},"string":"Hello World"}
Invalid argument(s)

行不通。

redis 127.0.0.1:6379> set test1 '{"array":[1,2,3],"number":123,"object":{"a":"b","c":"d","e":"f"},"string":"Hello World"}'
Invalid argument(s)

尝试单引号。是行不通的。

redis 127.0.0.1:6379> set test1 '{'"array'"':'[1',2',3']','"number'"':123','"object'"':'{'"a'"':'"b'"','"c'"':'"d'"','"e'"':'"f'"'},'"string'"':'"Hello World'"'}
Invalid argument(s)

尝试用反斜杠转义所有内容。是行不通的。

redis 127.0.0.1:6379> "'{'"array'"':'[1',2',3']','"number'"':123','"object'"':'{'"a'"':'"b'"','"c'"':'"d'"','"e'"':'"f'"'},'"string'"':'"Hello World'"'}"
OK

尝试用反斜杠和双引号转义所有内容。

它工作了!

redis 127.0.0.1:6379> get test1
"{'"array'":[1,2,3],'"number'":123,'"object'":{'"a'":'"b'",'"c'":'"d'",'"e'":'"f'"},'"string'":'"Hello World'"}"

现在在serialize()或json_encode()中有一个简单的参数,它允许这自动发生,

我必须使用preg_replace()编写一个自定义函数,在存储时添加斜杠,然后在检索时删除斜杠,并希望没有特定的棘手数据会破坏我自定义的基于regex的代码。

我觉得如果有合适的方法,第二种选择确实不可取。

你知道这样的选择是什么吗?

我无法使用Predis(我尝试https://github.com/nrk/predis/tree/php5.2_backport,因为我在PHP 5.2工作),但后来发现https://github.com/joelcox/codeigniter-redis,它适用于所有基本数据类型完美。

那么,serialize()/json_encode()的选项/参数是什么,它将允许一个redis-cli不会拒绝的字符串?

嗯,结果是第118行https://github.com/joelcox/codeigniter-redis/blob/develop/libraries/Redis.php

public function command($string)
{
    $slices = explode(' ', $string); /* <-- HERE  */
    $request = $this->_encode_request($slices[0], array_slice($slices, 1));
    return $this->_write_request($request);
}

盲目地用空格字符分隔整个命令。

因为我在我的数据中有空格(什么真实世界的数据没有…),这是打破Redis CLI语法。

所以我必须转义空格(替换为自定义字符串),使其正常工作