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

Skip to content

Commit d5b8f83

Browse files
bgortyatsukhnenko
authored andcommitted
rebase msgpack pull request (#801) on develop branch
1 parent 6a1685d commit d5b8f83

6 files changed

Lines changed: 170 additions & 5 deletions

File tree

common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ typedef enum _PUBSUB_TYPE {
8585
#define REDIS_SERIALIZER_NONE 0
8686
#define REDIS_SERIALIZER_PHP 1
8787
#define REDIS_SERIALIZER_IGBINARY 2
88+
#define REDIS_SERIALIZER_MSGPACK 3
8889
/* compression */
8990
#define REDIS_COMPRESSION_NONE 0
9091
#define REDIS_COMPRESSION_LZF 1

config.m4

100755100644
Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ dnl config.m4 for extension redis
33

44
PHP_ARG_ENABLE(redis, whether to enable redis support,
55
dnl Make sure that the comment is aligned:
6-
[ --enable-redis Enable redis support])
6+
[ --enable-redis Enable redis support])
77

8-
PHP_ARG_ENABLE(redis-session, whether to enable sessions,
9-
[ --disable-redis-session Disable session support], yes, no)
8+
PHP_ARG_ENABLE(redis-session, whether to disable sessions,
9+
[ --disable-redis-session Disable session support], yes, no)
1010

1111
PHP_ARG_ENABLE(redis-igbinary, whether to enable igbinary serializer support,
1212
[ --enable-redis-igbinary Enable igbinary serializer support], no, no)
@@ -16,6 +16,10 @@ PHP_ARG_ENABLE(redis-lzf, whether to enable lzf compression,
1616

1717
PHP_ARG_WITH(liblzf, use system liblzf,
1818
[ --with-liblzf[=DIR] Use system liblzf], no, no)
19+
[ --enable-redis-igbinary Enable igbinary serializer support], no, no)
20+
21+
PHP_ARG_ENABLE(redis-msgpack, whether to enable msgpack serializer support,
22+
[ --enable-redis-msgpack Enable msgpack serializer support], no, no)
1923

2024
if test "$PHP_REDIS" != "no"; then
2125

@@ -35,7 +39,7 @@ dnl Check for igbinary
3539
elif test -f "$phpincludedir/ext/igbinary/igbinary.h"; then
3640
igbinary_inc_path="$phpincludedir"
3741
else
38-
for i in php php4 php5 php6; do
42+
for i in php php4 php5 php6 php7; do
3943
if test -f "$prefix/include/$i/ext/igbinary/igbinary.h"; then
4044
igbinary_inc_path="$prefix/include/$i"
4145
fi
@@ -102,6 +106,48 @@ dnl Check for igbinary
102106
AC_DEFINE_UNQUOTED(GIT_REVISION, ["$(git log -1 --format=%H)"], [ ])
103107
fi
104108

109+
dnl Check for msgpack
110+
if test "$PHP_REDIS_MSGPACK" != "no"; then
111+
AC_MSG_CHECKING([for msgpack includes])
112+
msgpack_inc_path=""
113+
114+
if test -f "$abs_srcdir/include/php/ext/msgpack/php_msgpack.h"; then
115+
msgpack_inc_path="$abs_srcdir/include/php"
116+
elif test -f "$abs_srcdir/ext/msgpack/php_msgpack.h"; then
117+
msgpack_inc_path="$abs_srcdir"
118+
elif test -f "$phpincludedir/ext/msgpack/php_msgpack.h"; then
119+
msgpack_inc_path="$phpincludedir"
120+
else
121+
for i in php php4 php5 php6 php7; do
122+
if test -f "$prefix/include/$i/ext/msgpack/php_msgpack.h"; then
123+
msgpack_inc_path="$prefix/include/$i"
124+
fi
125+
done
126+
fi
127+
128+
if test "$msgpack_inc_path" = ""; then
129+
AC_MSG_ERROR([Cannot find php_msgpack.h])
130+
else
131+
AC_MSG_RESULT([$msgpack_inc_path])
132+
fi
133+
fi
134+
135+
AC_MSG_CHECKING([for redis msgpack support])
136+
if test "$PHP_REDIS_MSGPACK" != "no"; then
137+
AC_MSG_RESULT([enabled])
138+
AC_DEFINE(HAVE_REDIS_MSGPACK,1,[Whether redis msgpack serializer is enabled])
139+
MSGPACK_INCLUDES="-I$msgpack_inc_path"
140+
MSGPACK_EXT_DIR="$msgpack_inc_path/ext"
141+
ifdef([PHP_ADD_EXTENSION_DEP],
142+
[
143+
PHP_ADD_EXTENSION_DEP(redis, msgpack)
144+
])
145+
PHP_ADD_INCLUDE($MSGPACK_EXT_DIR)
146+
else
147+
MSGPACK_INCLUDES=""
148+
AC_MSG_RESULT([disabled])
149+
fi
150+
105151
dnl # --with-redis -> check with-path
106152
dnl SEARCH_PATH="/usr/local /usr" # you might want to change this
107153
dnl SEARCH_FOR="/include/redis.h" # you most likely want to change this

library.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
#ifdef HAVE_REDIS_IGBINARY
1010
#include "igbinary/igbinary.h"
1111
#endif
12+
#ifdef HAVE_REDIS_MSGPACK
13+
#include "msgpack/php_msgpack.h"
14+
#endif
1215

1316
#ifdef HAVE_REDIS_LZF
1417
#include <lzf.h>
@@ -1894,6 +1897,7 @@ PHP_REDIS_API int redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAMETERS,
18941897
}
18951898
return -1;
18961899
}
1900+
18971901
numElems = atoi(inbuf+1);
18981902
zval z_multi_result;
18991903
array_init(&z_multi_result); /* pre-allocate array for multi's results. */
@@ -1910,6 +1914,67 @@ PHP_REDIS_API int redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAMETERS,
19101914
return 0;
19111915
}
19121916

1917+
/**
1918+
* redis_sock_read_multibulk_reply_vals
1919+
*
1920+
* This is identical to redis_sock_read_multibulk_reply except that it unserializes vals only, rather than rely on
1921+
* the chosen unserializer to silently return 0 after a failed attempt (which msgpack does not do).
1922+
*
1923+
* Perhaps not the optimal solution, but the easiest way to resolve the problem of failed attempts to
1924+
* unserialize a key that hadn't been serialized to begin with in blpop, brpop.
1925+
*
1926+
*/
1927+
PHP_REDIS_API int redis_sock_read_multibulk_reply_vals(INTERNAL_FUNCTION_PARAMETERS,
1928+
RedisSock *redis_sock, zval *z_tab,
1929+
void *ctx)
1930+
{
1931+
char inbuf[1024];
1932+
int numElems, err_len;
1933+
1934+
if(-1 == redis_check_eof(redis_sock, 0 TSRMLS_CC)) {
1935+
return -1;
1936+
}
1937+
1938+
if(php_stream_gets(redis_sock->stream, inbuf, 1024) == NULL) {
1939+
REDIS_STREAM_CLOSE_MARK_FAILED(redis_sock);
1940+
zend_throw_exception(redis_exception_ce, "read error on connection", 0
1941+
TSRMLS_CC);
1942+
return -1;
1943+
}
1944+
1945+
if(inbuf[0] != '*') {
1946+
IF_MULTI_OR_PIPELINE() {
1947+
add_next_index_bool(z_tab, 0);
1948+
} else {
1949+
if (inbuf[0] == '-') {
1950+
err_len = strlen(inbuf+1) - 2;
1951+
redis_sock_set_err(redis_sock, inbuf+1, err_len);
1952+
}
1953+
RETVAL_FALSE;
1954+
}
1955+
return -1;
1956+
}
1957+
1958+
numElems = atoi(inbuf+1);
1959+
zval zv, *z_multi_result = &zv;
1960+
#if (PHP_MAJOR_VERSION < 7)
1961+
MAKE_STD_ZVAL(z_multi_result);
1962+
#endif
1963+
array_init(z_multi_result); /* pre-allocate array for multi's results. */
1964+
1965+
redis_mbulk_reply_loop(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock,
1966+
z_multi_result, numElems, UNSERIALIZE_VALS);
1967+
1968+
IF_MULTI_OR_PIPELINE() {
1969+
add_next_index_zval(z_tab, z_multi_result);
1970+
} else {
1971+
RETVAL_ZVAL(z_multi_result, 0, 1);
1972+
}
1973+
/*zval_copy_ctor(return_value); */
1974+
return 0;
1975+
}
1976+
1977+
19131978
/* Like multibulk reply, but don't touch the values, they won't be unserialized
19141979
* (this is used by HKEYS). */
19151980
PHP_REDIS_API int
@@ -2195,6 +2260,17 @@ redis_serialize(RedisSock *redis_sock, zval *z, char **val, size_t *val_len
21952260
PHP_VAR_SERIALIZE_DESTROY(ht);
21962261

21972262
return 1;
2263+
2264+
case REDIS_SERIALIZER_MSGPACK:
2265+
#ifdef HAVE_REDIS_MSGPACK
2266+
php_msgpack_serialize(&sstr, z TSRMLS_CC);
2267+
*val = estrndup(sstr.s->val, sstr.s->len);
2268+
*val_len = sstr.s->len;
2269+
smart_str_free(&sstr);
2270+
2271+
return 1;
2272+
#endif
2273+
break;
21982274
case REDIS_SERIALIZER_IGBINARY:
21992275
#ifdef HAVE_REDIS_IGBINARY
22002276
if(igbinary_serialize(&val8, (size_t *)&sz, z TSRMLS_CC) == 0) {
@@ -2205,6 +2281,7 @@ redis_serialize(RedisSock *redis_sock, zval *z, char **val, size_t *val_len
22052281
#endif
22062282
break;
22072283
}
2284+
22082285
return 0;
22092286
}
22102287

@@ -2227,6 +2304,19 @@ redis_unserialize(RedisSock* redis_sock, const char *val, int val_len,
22272304
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
22282305
break;
22292306

2307+
case REDIS_SERIALIZER_MSGPACK:
2308+
#ifdef HAVE_REDIS_MSGPACK
2309+
/*
2310+
* Would like to be able to check to see if a string is msgpack'd (like with igbinary, below),
2311+
* but I don't believe there's an easy way to do that as there's no consistent header or
2312+
* other simple indication of packed-ness in msgpacked binary sequences, as far as I know.
2313+
*/
2314+
2315+
php_msgpack_unserialize(z_ret, (char *)val, (size_t)val_len TSRMLS_CC);
2316+
ret = 1;
2317+
#endif
2318+
break;
2319+
22302320
case REDIS_SERIALIZER_IGBINARY:
22312321
#ifdef HAVE_REDIS_IGBINARY
22322322
/*
@@ -2257,6 +2347,7 @@ redis_unserialize(RedisSock* redis_sock, const char *val, int val_len,
22572347
#endif
22582348
break;
22592349
}
2350+
22602351
return ret;
22612352
}
22622353

redis.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,10 @@ static void add_class_constants(zend_class_entry *ce, int is_cluster TSRMLS_DC)
693693
zend_declare_class_constant_long(ce, ZEND_STRL("FAILOVER_DISTRIBUTE_SLAVES"), REDIS_FAILOVER_DISTRIBUTE_SLAVES TSRMLS_CC);
694694
}
695695

696+
#ifdef HAVE_REDIS_MSGPACK
697+
zend_declare_class_constant_long(ce, ZEND_STRL("SERIALIZER_MSGPACK"), REDIS_SERIALIZER_MSGPACK TSRMLS_CC);
698+
#endif
699+
696700
zend_declare_class_constant_stringl(ce, "AFTER", 5, "after", 5 TSRMLS_CC);
697701
zend_declare_class_constant_stringl(ce, "BEFORE", 6, "before", 6 TSRMLS_CC);
698702
}

redis_commands.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3886,6 +3886,9 @@ void redis_setoption_handler(INTERNAL_FUNCTION_PARAMETERS,
38863886
if (val_long == REDIS_SERIALIZER_NONE || val_long == REDIS_SERIALIZER_PHP
38873887
#ifdef HAVE_REDIS_IGBINARY
38883888
|| val_long == REDIS_SERIALIZER_IGBINARY
3889+
#endif
3890+
#ifdef HAVE_REDIS_MSGPACK
3891+
|| val_long == REDIS_SERIALIZER_MSGPACK
38893892
#endif
38903893
) {
38913894
redis_sock->serializer = val_long;

tests/RedisTest.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4223,6 +4223,17 @@ public function testSerializerIGBinary() {
42234223
}
42244224
}
42254225

4226+
public function testSerializerMsgPack() {
4227+
if(defined('Redis::SERIALIZER_MSGPACK')) {
4228+
$this->checkSerializer(Redis::SERIALIZER_MSGPACK);
4229+
4230+
// with prefix
4231+
$this->redis->setOption(Redis::OPT_PREFIX, "test:");
4232+
$this->checkSerializer(Redis::SERIALIZER_MSGPACK);
4233+
$this->redis->setOption(Redis::OPT_PREFIX, "");
4234+
}
4235+
}
4236+
42264237
private function checkSerializer($mode) {
42274238

42284239
$this->redis->del('key');
@@ -4716,6 +4727,10 @@ public function testSerialize() {
47164727
$arr_serializers[] = Redis::SERIALIZER_IGBINARY;
47174728
}
47184729

4730+
if(defined('Redis::SERIALIZER_MSGPACK')) {
4731+
$arr_serializers[] = Redis::SERIALIZER_MSGPACK;
4732+
}
4733+
47194734
foreach($arr_serializers as $mode) {
47204735
$arr_enc = [];
47214736
$arr_dec = [];
@@ -4735,11 +4750,16 @@ public function testUnserialize() {
47354750
1,1.5,'one',['this','is','an','array']
47364751
];
47374752

4738-
$serializers = [Redis::SERIALIZER_PHP];
4753+
$serializers = Array(Redis::SERIALIZER_PHP);
4754+
47394755
if(defined('Redis::SERIALIZER_IGBINARY')) {
47404756
$serializers[] = Redis::SERIALIZER_IGBINARY;
47414757
}
47424758

4759+
if(defined('Redis::SERIALIZER_MSGPACK')) {
4760+
$serializers[] = Redis::SERIALIZER_MSGPACK;
4761+
}
4762+
47434763
foreach($serializers as $mode) {
47444764
$vals_enc = [];
47454765

0 commit comments

Comments
 (0)