_serialize method

This commit adds a utility method as a counterpart to the _unserialize
utility method, allowing users to manually serialize data themselves
before sending it to Redis.  This could be useful for calls going through
EVAL, as phpredis can't automatically serialize/unserialize in that case.

Addresses #431
This commit is contained in:
michael-grunder
2014-02-04 11:55:08 -08:00
parent 1a89ec2ff4
commit f200730fe9
4 changed files with 82 additions and 0 deletions

View File

@@ -2990,6 +2990,7 @@ $ret = FALSE if x has been modified between the call to WATCH and the call to EX
* [clearLastError](#) - Clear the last error message
* [_prefix](#) - A utility method to prefix the value with the prefix setting for phpredis
* [_unserialize](#) - A utility method to unserialize data with whatever serializer is set up
* [_serialize](#) - A utility method to serialize data with whatever serializer is set up
### eval
-----
@@ -3139,6 +3140,28 @@ $redis->setOption(Redis::OPT_PREFIX, 'my-prefix:');
$redis->_prefix('my-value'); // Will return 'my-prefix:my-value'
~~~
### _serialize
-----
_**Description**_: A utility method to serialize values manually.
This method allows you to serialize a value with whatever serializer is configured, manually.
This can be useful for serialization/unserialization of data going in and out of EVAL commands
as phpredis can't automatically do this itself. Note that if no serializer is set, phpredis
will change Array values to 'Array', and Objects to 'Object'.
##### *Parameters*
*value*: Mixed. The value to be serialized
##### *Examples*
~~~
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE);
$redis->_serialize("foo"); // returns "foo"
$redis->_serialize(Array()); // Returns "Array"
$redis->_serialize(new stdClass()); // Returns "Object"
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);
$redis->_serialize("foo"); // Returns 's:3:"foo";'
### _unserialize
-----
_**Description**_: A utility method to unserialize data with whatever serializer is set up.

View File

@@ -142,6 +142,7 @@ PHP_METHOD(Redis, time);
PHP_METHOD(Redis, getLastError);
PHP_METHOD(Redis, clearLastError);
PHP_METHOD(Redis, _prefix);
PHP_METHOD(Redis, _serialize);
PHP_METHOD(Redis, _unserialize);
PHP_METHOD(Redis, mset);

30
redis.c
View File

@@ -245,6 +245,7 @@ static zend_function_entry redis_functions[] = {
PHP_ME(Redis, clearLastError, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, _prefix, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, _serialize, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, _unserialize, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, client, NULL, ZEND_ACC_PUBLIC)
@@ -6458,6 +6459,35 @@ PHP_METHOD(Redis, _prefix) {
}
}
/*
* {{{ proto Redis::_serialize(value)
*/
PHP_METHOD(Redis, _serialize) {
zval *object;
RedisSock *redis_sock;
zval *z_val;
char *val;
int val_free, val_len;
// Parse arguments
if(zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz",
&object, redis_ce, &z_val) == FAILURE)
{
RETURN_FALSE;
}
// Grab socket
if(redis_sock_get(object, &redis_sock TSRMLS_CC, 0) < 0) {
RETURN_FALSE;
}
// Serialize, which will return a value even if no serializer is set
val_free = redis_serialize(redis_sock, z_val, &val, &val_len TSRMLS_CC);
// Return serialized value. Tell PHP to make a copy if redis_serialize didn't.
RETURN_STRINGL(val, val_len, !val_free);
}
/*
* {{{ proto Redis::_unserialize(value)
*/

View File

@@ -4428,6 +4428,34 @@ class Redis_Test extends TestSuite
$this->assertTrue(1 === $this->redis->evalsha($sha));
}
public function testSerialize() {
$vals = Array(1, 1.5, 'one', Array('here','is','an','array'));
// Test with no serialization at all
$this->assertTrue($this->redis->_serialize('test') === 'test');
$this->assertTrue($this->redis->_serialize(1) === '1');
$this->assertTrue($this->redis->_serialize(Array()) === 'Array');
$this->assertTrue($this->redis->_serialize(new stdClass) === 'Object');
$arr_serializers = Array(Redis::SERIALIZER_PHP);
if(defined('Redis::SERIALIZER_IGBINARY')) {
$arr_serializers[] = Redis::SERIALIZER_IGBINARY;
}
foreach($arr_serializers as $mode) {
$arr_enc = Array();
$arr_dec = Array();
foreach($vals as $k => $v) {
$enc = $this->redis->_serialize($v);
$dec = $this->redis->_unserialize($enc);
// They should be the same
$this->assertTrue($enc == $dec);
}
}
}
public function testUnserialize() {
$vals = Array(
1,1.5,'one',Array('this','is','an','array')