Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7aa70f5

Browse files
Experimental JSON support
Highly experimental support for JSON added. There are a few important things to consider with JSON (specifically as it relates to PHP) Most importantly, is how we would want data to be decoded. By default, PHP will decode JSON values into a stdClass object. This works if you're checking for that, but will not necissarily work if you're looking for an array to come back as an array. For this commit I have decided to decode as associative until I can determine the best way to handle this. If we ever decide to incorporate JSON into the main branch, this will likely need to become another option set by the user. In addition, I am attempting to find an example of json_decode_ex, and json_encode being called (outside of php_json.c iteslf) where I can test for error conditions. With this commit, the unit tests are passing with the exception of object encoding/decoding.
1 parent 7dfac44 commit 7aa70f5

File tree

5 files changed

+72
-5
lines changed

5 files changed

+72
-5
lines changed

common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ typedef enum _REDIS_REPLY_TYPE {
3939
#define REDIS_SERIALIZER_NONE 0
4040
#define REDIS_SERIALIZER_PHP 1
4141
#define REDIS_SERIALIZER_IGBINARY 2
42+
#define REDIS_SERIALIZER_JSON 3
4243

4344
#define IF_MULTI() if(redis_sock->mode == MULTI)
4445
#define IF_MULTI_OR_ATOMIC() if(redis_sock->mode == MULTI || redis_sock->mode == ATOMIC)\

library.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,20 @@
1010
#endif
1111
#include <ext/standard/php_smart_str.h>
1212
#include <ext/standard/php_var.h>
13+
1314
#ifdef HAVE_REDIS_IGBINARY
1415
#include "igbinary/igbinary.h"
1516
#endif
17+
18+
#ifdef HAVE_JSON
19+
#include <ext/json/php_json.h>
20+
21+
// Define defualt depth if we don't have it
22+
#ifndef JSON_PARSER_DEFAULT_DEPTH
23+
#define JSON_PARSER_DEFAULT_DEPTH 512
24+
#endif
25+
#endif
26+
1627
#include <zend_exceptions.h>
1728
#include "php_redis.h"
1829
#include "library.h"
@@ -1313,6 +1324,22 @@ redis_serialize(RedisSock *redis_sock, zval *z, char **val, int *val_len TSRMLS_
13131324
*val_len = (int)sz;
13141325
return 1;
13151326
}
1327+
#endif
1328+
return 0;
1329+
case REDIS_SERIALIZER_JSON:
1330+
#ifdef HAVE_JSON
1331+
#if PHP_VERSION_ID >= 50399
1332+
php_json_encode(&sstr, z, 0 TSRMLS_CC);
1333+
#else
1334+
php_json_encode(&sstr, z, TSRMLS_CC);
1335+
#endif
1336+
1337+
// Return our value and length
1338+
*val = sstr.c;
1339+
*val_len = (int)sstr.len;
1340+
1341+
// Success
1342+
return 1;
13161343
#endif
13171344
return 0;
13181345
}
@@ -1365,7 +1392,21 @@ redis_unserialize(RedisSock *redis_sock, const char *val, int val_len, zval **re
13651392
#endif
13661393
return 0;
13671394
break;
1395+
#ifdef HAVE_JSON
1396+
case REDIS_SERIALIZER_JSON:
1397+
if(!*return_value) {
1398+
MAKE_STD_ZVAL(*return_value);
1399+
}
1400+
#if PHP_VERSION_ID >= 50399
1401+
php_json_decode_ex(*return_value, val, val_len, PHP_JSON_OBJECT_AS_ARRAY, JSON_PARSER_DEFAULT_DEPTH TSRMLS_CC);
1402+
#else
1403+
php_json_decode(*return_value, val, val_len, 1, JSON_PARSER_DEFAULT_DEPTH TSRMLS_CC);
1404+
#endif
1405+
return 1;
1406+
break;
1407+
#endif
13681408
}
1409+
13691410
return 0;
13701411
}
13711412

redis.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,6 @@
4040

4141
#include "library.h"
4242

43-
#define R_SUB_CALLBACK_CLASS_TYPE 1
44-
#define R_SUB_CALLBACK_FT_TYPE 2
45-
#define R_SUB_CLOSURE_TYPE 3
46-
4743
int le_redis_sock;
4844
extern int le_redis_array;
4945

@@ -441,6 +437,9 @@ PHP_MINIT_FUNCTION(redis)
441437
#ifdef HAVE_REDIS_IGBINARY
442438
add_constant_long(redis_ce, "SERIALIZER_IGBINARY", REDIS_SERIALIZER_IGBINARY);
443439
#endif
440+
#ifdef HAVE_JSON
441+
add_constant_long(redis_ce, "SERIALIZER_JSON", REDIS_SERIALIZER_JSON);
442+
#endif
444443

445444
zend_declare_class_constant_stringl(redis_ce, "AFTER", 5, "after", 5 TSRMLS_CC);
446445
zend_declare_class_constant_stringl(redis_ce, "BEFORE", 6, "before", 6 TSRMLS_CC);
@@ -5681,6 +5680,9 @@ PHP_METHOD(Redis, setOption) {
56815680
if(val_long == REDIS_SERIALIZER_NONE
56825681
#ifdef HAVE_REDIS_IGBINARY
56835682
|| val_long == REDIS_SERIALIZER_IGBINARY
5683+
#endif
5684+
#ifdef HAVE_JSON
5685+
|| val_long == REDIS_SERIALIZER_JSON
56845686
#endif
56855687
|| val_long == REDIS_SERIALIZER_PHP) {
56865688
redis_sock->serializer = val_long;

tests/TestRedis.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2189,6 +2189,8 @@ public function testPipeline() {
21892189
}
21902190

21912191
protected function sequence($mode) {
2192+
// Kill some keys as this is called multiple times
2193+
$this->redis->del('zkey1', 'zkey2', 'zKey5', 'zInter', 'zUnion');
21922194

21932195
$ret = $this->redis->multi($mode)
21942196
->set('x', 42)
@@ -2649,6 +2651,7 @@ protected function sequence($mode) {
26492651

26502652
$i = 0;
26512653
$this->assertTrue(is_array($ret));
2654+
26522655
$this->assertTrue(is_long($ret[$i]) && $ret[$i] >= 0 && $ret[$i] <= 3); $i++; // deleting at most 3 keys
26532656
$this->assertTrue($ret[$i++] === 1);
26542657
$this->assertTrue($ret[$i++] === 1);
@@ -2771,6 +2774,17 @@ public function testSerializerIGBinary() {
27712774
}
27722775
}
27732776

2777+
public function testSerializerJSON() {
2778+
if(defined('Redis::SERIALIZER_JSON')) {
2779+
$this->checkSerializer(Redis::SERIALIZER_JSON);
2780+
2781+
// wITH PREFIX
2782+
$this->redis->setOption(Redis::OPT_PREFIX, "test:");
2783+
$this->checkSerializer(Redis::SERIALIZER_JSON);
2784+
$this->redis->setOption(Redis::OPT_PREFIX, "");
2785+
}
2786+
}
2787+
27742788
private function checkSerializer($mode) {
27752789

27762790
$this->redis->delete('key');
@@ -3241,7 +3255,15 @@ public function testUnserialize() {
32413255
1,1.5,'one',Array('this','is','an','array')
32423256
);
32433257

3244-
foreach(Array(Redis::SERIALIZER_PHP, Redis::SERIALIZER_IGBINARY) as $mode) {
3258+
$serializers = Array(Redis::SERIALIZER_PHP);
3259+
if(defined('Redis::SERIALIZER_IGBINARY')) {
3260+
$serializers[] = Redis::SERIALIZER_IGBINARY;
3261+
}
3262+
if(defined('Redis::SERIALIZER_JSON')) {
3263+
$serializers[] = Redis::SERIALIZER_JSON;
3264+
}
3265+
3266+
foreach($serializers as $mode) {
32453267
$vals_enc = Array();
32463268

32473269
// Pass them through redis so they're serialized

tests/test.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public static function run($className) {
4343
$methods = $rc->GetMethods(ReflectionMethod::IS_PUBLIC);
4444

4545
foreach($methods as $m) {
46+
if(strtolower($m->name) != 'testserializerjson') continue;
4647

4748
$name = $m->name;
4849
if(substr($name, 0, 4) !== 'test')

0 commit comments

Comments
 (0)