我是靠谱客的博主 大胆老鼠,最近开发中收集的这篇文章主要介绍Go解析php-mem扩展写入的数据(序列化+zlib),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

原因:工作中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

package 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扩展写入的数据(序列化+zlib)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部