原因:工作中php使用mem,有直接jsonencode方式的写入,使用目前的mem插件就能很好的去读,但是php中可以直接写入mem一个数组类型,这种情况,php-mem扩展会先进行自身的序列化然后zlib存储到mem中,Go取出的数据,二进制使用binary解析出为乱码,问题进行解决
找到一个git源
How to read fastlz or zlib php compressed memcache key from go · GitHub
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49package main import ( "encoding/binary" "errors" "github.com/bradfitz/gomemcache/memcache" "github.com/digitalcrab/fastlz" ) // 这个地址需要认真看下,只有看了这个才知道 怎么区分 两种压缩方式 see https://github.com/php-memcached-dev/php-memcached/blob/master/php_memcached.c#L101 const MEMC_VAL_COMPRESSED = (1 << 0) // 1 const MEMC_VAL_COMPRESSION_ZLIB = (1 << 1) // 10 const MEMC_VAL_COMPRESSION_FASTLZ = (1 << 2) // 100 const MAX_MEMORY_ALLOWED_FOR_MEMCACHE uint = 1024 * 1024 * 1.5 // 1.5MB func GetDataFromCache(cacheKey string) (data []byte, err error) { var decompressedValue []byte returnData, err := MemcacheClient.Get(cacheKey) if err != nil { // maybe pass the original error if err != memcache.ErrCacheMiss return nil, errors.New("Cache key not found or get action failed") } if returnData.Flags > 0 && ((returnData.Flags>>4)&MEMC_VAL_COMPRESSED) > 0 && ((returnData.Flags>>4)&MEMC_VAL_COMPRESSION_FASTLZ) > 0 { //前4个字节存储的是数据长度,需要单独截取出来,解析出错的原因根本所在找到了,后续处理的问题就简单了,GO默认是小端的获取数据方式 // first 4 bytes contain the length in little endian format (right to left), the content starts from the 5th byte dataLength := uint(binary.LittleEndian.Uint32(returnData.Value[:4])) if dataLength > MAX_MEMORY_ALLOWED_FOR_MEMCACHE { return nil, errors.New("Could not uncompress data, too large") } decompressedValue, err = fastlz.Decompress(returnData.Value[4:], dataLength) if err != nil { return nil, err } return decompressedValue, nil } else if returnData.Flags > 0 && ((returnData.Flags>>4)&MEMC_VAL_COMPRESSED) > 0 && ((returnData.Flags>>4)&MEMC_VAL_COMPRESSION_ZLIB) > 0 { // you will need to implement it, but most probably // it will be in the same format with the first 4 bytes representing // the length and the rest being the data. See https://golang.org/pkg/compress/zlib/ //这块儿作者没有实现,自己也可以比较容易的实现,同fashlz方式 } return returnData.Value, nil } func main () { // you need to connect to memcache here }
记录下学习下
最后
以上就是大胆老鼠最近收集整理的关于Go解析php-mem扩展写入的数据(序列化+zlib)的全部内容,更多相关Go解析php-mem扩展写入内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复