文档章节

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

anoty
 anoty
发布于 08/09 15:37
字数 465
阅读 253
收藏 2

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架构师

© 著作权归作者所有

共有 人打赏支持
anoty
粉丝 23
博文 37
码字总数 23921
作品 0
浦东
Redis windows下安装

1.安装 (1)windows把redisbinx64安装包放在电脑任意的盘里 (2)通过cmd找到对应目录: Dredisbinx64 (3)开始启动redis服务 Dredisbin_x64redis-server.exe 代表的redis安装成功 (4)开启redis客...

方花
04/24
0
0
redis和memcache的区别

memcache官方定义 Free & open source, high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications ......

山鹰sniper
2014/07/16
0
0
Linxu下Redis+PHP扩展的安装和Redis集群的配置【转】

redis下载: http://redis.io/download 多台服务安装: http://www.vquickphp.com/?a=blogview&id=30 开机加自启动:echo "redis-server /thepathtoredis_conf/redis.conf" >>/etc/rc.local......

big_cat
2015/07/07
0
0
本地缓存库--libshmcache

libshmcache是基于共享内存的本地缓存库,可以在多个非亲缘关系的进程间共享缓存。libshmcache写有锁,读无锁,性能非常高。libshmcache直接访问本地共享内存,速度比远程接口如redis快100倍...

fastdfs
2017/03/08
268
0
Spring Boot使用Spring Data Redis操作Redis(单机/集群)

说明:Spring Boot简化了Spring Data Redis的引入,只要引入spring-boot-starter-data-redis之后会自动下载相应的Spring Data Redis和Jedis客户端,可以减少版本这块的冲突,当然,如果要引入...

easonjim
2017/11/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS7防火墙firewalld操作

firewalld Linux上新用的防火墙软件,跟iptables差不多的工具。 firewall-cmd 是 firewalld 的字符界面管理工具,firewalld是CentOS7的一大特性,最大的好处有两个:支持动态更新,不用重启服...

dingdayu
今天
1
0
关于组件化的最初步

一个工程可能会有多个版本,有国际版、国内版、还有针对各种不同的渠道化的打包版本、这个属于我们日常经常见到的打包差异化版本需求。 而对于工程的开发,比如以前的公司,分成了有三大块业...

DannyCoder
今天
2
0
Spring的Resttemplate发送带header的post请求

private HttpHeaders getJsonHeader() { HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); ......

qiang123
昨天
3
0
Spring Cloud Gateway 之 Only one connection receive subscriber allowed

都说Spring Cloud Gateway好,我也来试试,可是配置了总是报下面这个错误: java.lang.IllegalStateException: Only one connection receive subscriber allowed. 困扰了我几天的问题,原来...

ThinkGem
昨天
27
0
学习设计模式——观察者模式

1. 认识观察者模式 1. 定义:定义对象之间一种一对多的依赖关系,当一个对象状态发生变化时,依赖该对象的其他对象都会得到通知并进行相应的变化。 2. 组织结构: Subject:目标对象类,会被...

江左煤郎
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部