I am trying to store JSON data in Redis through PHP, but testing it through the redis-cli command line client.
In both clients, I seem to be unable to store JSON without escaping it somehow.
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)
Doesn't work.
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)
Tried single quotes. Doesn't work.
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)
Tried escaping everything with backslashes. Doesn't work.
redis 127.0.0.1:6379> "\{\"array\"\:\[1\,2\,3\]\,\"number\"\:123\,\"object\"\:\{\"a\"\:\"b\"\,\"c\"\:\"d\"\,\"e\"\:\"f\"\},\"string\"\:\"Hello World\"\}"
OK
Tried escaping everything with backslashes and in double quotes.
And it works!
redis 127.0.0.1:6379> get test1
"{\"array\":[1,2,3],\"number\":123,\"object\":{\"a\":\"b\",\"c\":\"d\",\"e\":\"f\"},\"string\":\"Hello World\"}"
Now either there is a simple parameter in serialize() or json_encode() which allows this to happen automatically,
OR
I have to write a custom function using preg_replace() to add slashes while storing and then remove slashes while retrieving, and hope that there is no specific tricky data that will break my custom regex based code.
I feel that the second option is really not advisable if there is a proper way to do it.
Any ideas what such an option would be?
I am unable to use Predis (I tried https://github.com/nrk/predis/tree/php5.2_backport because I am working on PHP 5.2) but then found https://github.com/joelcox/codeigniter-redis and it works for all basic data types perfectly.
So, what is the option / parameter to serialize() / json_encode() that will allow a string which redis-cli won't reject?
Well, it turns out that line 118 at 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);
}
was blindly splitting the entire command by the space character.
Since I had spaces in my data (what real world data does not...), this was breaking Redis CLI syntax.
So I had to escape spaces (replaced by custom string) to get it to work properly.