不要开启 php redis 扩展的自动序列化选项

php redis 扩展有自动序列化选项,在存储kv数据的时候,可以少写点代码就打开了,使用的过程中忽然发现了一个令人郁闷的地方。

扩展没有对你要存储的值做类型判断,任何类型的值都做了自动序列化,比如下面这段代码


$rd = new Redis();
$r = $rd->connect(
    '127.0.0.1', 6379, 1
);
$rd->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);
$rd->set('k', 1);
var_dump($rd->incr('k'));
echo $rd->getLastError(), PHP_EOL;
echo $rd->get('k');

你存储了一个int进去,然后在incr,就会失败


bool(false)
ERR value is not an integer or out of range

1

直接用redis-cli去看下,发现,value 被序列化了


127.0.0.1:6379> get k

"i:1;"

这是php redis 扩展序列化的部分代码(在源码包的library.c),你会发现,这个序列化并没有像memcached扩展一样做类型判断,而是全部序列化。


PHP_REDIS_API int
redis_serialize(RedisSock *redis_sock, zval *z, char **val, strlen_t *val_len
                TSRMLS_DC)
{
    ……
    switch(redis_sock->serializer) {
        case REDIS_SERIALIZER_NONE:
        ……
        case REDIS_SERIALIZER_PHP:
#if ZEND_MODULE_API_NO >= 20100000
            PHP_VAR_SERIALIZE_INIT(ht);
#else
            zend_hash_init(&ht, 10, NULL, NULL, 0);
#endif
            php_var_serialize(&sstr, z, &ht);
#if (PHP_MAJOR_VERSION < 7)
            *val = estrndup(sstr.c, sstr.len);
            *val_len = sstr.len;
#else
            *val = estrndup(ZSTR_VAL(sstr.s), ZSTR_LEN(sstr.s));
            *val_len = ZSTR_LEN(sstr.s);
#endif
            smart_str_free(&sstr);
#if ZEND_MODULE_API_NO >= 20100000
            PHP_VAR_SERIALIZE_DESTROY(ht);
#else
            zend_hash_destroy(&ht);
#endif
            return 1;
        case REDIS_SERIALIZER_IGBINARY:
        ……

    }
    return 0;
}

看来php redis 这扩展出来这么久,用户量这么大,但是文档都没进到php官方文档,也不是没有原因的。

更多架构、PHP、GO相关踩坑实践技巧请关注我的公众号:PHP架构师

转载于:https://my.oschina.net/u/222608/blog/1925135

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值