如何在Go Redis客户端用igbinary序列化GET/SET及读取PHP存入的Redis值?
关于Go Redis客户端与igbinary序列化的问题解答
1. 在Go Redis客户端中使用igbinary进行GET/SET序列化
要实现igbinary序列化的GET/SET操作,需借助支持igbinary编解码的Go库,主流选择是github.com/ugorji/go/codec。以下基于常用的go-redis/redis(v8+版本)给出实现方案:
步骤1:安装依赖库
go get github.com/ugorji/go/codec go get github.com/go-redis/redis/v8
步骤2:自定义igbinary序列化客户端
通过包装原生Redis客户端,替换默认的序列化逻辑:
package main import ( "context" "github.com/go-redis/redis/v8" "github.com/ugorji/go/codec" ) var igbHandle codec.Handle func init() { // 初始化igbinary编解码器实例 igbHandle = new(codec.IgbinaryHandle) } // IgbinaryRedisClient 封装原生客户端,实现igbinary序列化逻辑 type IgbinaryRedisClient struct { *redis.Client } // Set 序列化值后存入Redis func (c *IgbinaryRedisClient) Set(ctx context.Context, key string, value interface{}, opts *redis.SetOptions) *redis.StatusCmd { var buf []byte enc := codec.NewEncoderBytes(&buf, igbHandle) if err := enc.Encode(value); err != nil { return redis.NewStatusCmd(ctx).SetErr(err) } return c.Client.Set(ctx, key, buf, opts) } // Get 读取Redis值并反序列化到目标变量 func (c *IgbinaryRedisClient) Get(ctx context.Context, key string, dest interface{}) error { cmd := c.Client.Get(ctx, key) if err := cmd.Err(); err != nil { return err } buf, err := cmd.Bytes() if err != nil { return err } dec := codec.NewDecoderBytes(buf, igbHandle) return dec.Decode(dest) }
步骤3:使用自定义客户端
func main() { ctx := context.Background() client := &IgbinaryRedisClient{ Client: redis.NewClient(&redis.Options{ Addr: "localhost:6379", }), } // 存入数据 user := map[string]interface{}{"name": "Alice", "age": 30} if err := client.Set(ctx, "user:1", user, nil).Err(); err != nil { panic(err) } // 读取数据 var retrievedUser map[string]interface{} if err := client.Get(ctx, "user:1", &retrievedUser); err != nil { panic(err) } println(retrievedUser["name"].(string)) // 输出 Alice }
2. 读取PHP服务用igbinary存入Redis的值
PHP的igbinary序列化格式与ugorji/go/codec库兼容,只需注意PHP与Go的类型映射规则:
- PHP关联数组 → Go的
map[string]interface{} - PHP索引数组 → Go的
[]interface{} - PHP基础类型(字符串/数字)→ Go对应基础类型
- PHP自定义对象 → Go需定义匹配字段的结构体(可通过
codec标签映射属性名)
示例代码
package main import ( "context" "github.com/go-redis/redis/v8" "github.com/ugorji/go/codec" ) var igbHandle codec.Handle = new(codec.IgbinaryHandle) func main() { ctx := context.Background() client := redis.NewClient(&redis.Options{ Addr: "localhost:6379", }) // 读取Redis中PHP存入的igbinary数据 cmd := client.Get(ctx, "php:data") buf, err := cmd.Bytes() if err != nil { panic(err) } // 反序列化到Go类型(假设PHP存的是关联数组) var phpData map[string]interface{} dec := codec.NewDecoderBytes(buf, igbHandle) if err := dec.Decode(&phpData); err != nil { panic(err) } println("PHP存储的name值:", phpData["name"].(string)) }
自定义对象映射示例
若PHP存入的是自定义对象,Go端需定义对应结构体并通过标签映射属性:
type PHPUser struct { Name string `codec:"name"` // 对应PHP对象的$name属性 Age int `codec:"age"` // 对应PHP对象的$age属性 } // 反序列化时直接传入PHPUser指针 var user PHPUser dec.Decode(&user)
内容的提问来源于stack exchange,提问作者Ginger
相关产品推荐
相关产品推荐

