php - 迭代从 PHP 序列化格式解码的 map

标签 php go deserialization

我如何以 map 格式读取 golang 中的条件 反序列化数据?

[map[19:map[conditions:map[0:map[operator:== value:AMW-1900-50SLE-ROOM 
is_value_processed:false type:feedexport/rule_condition_product 
attribute:sku] 1:map[type:feedexport/rule_condition_product 
attribute:sku operator:== value:ASL-B654-77-74-98-ROOM 
is_value_processed:false] 2:map[is_value_processed:false 
type:feedexport/rule_condition_product attribute:sku operator:== 
value:ASL-B217-57-54S-95-ROOM]] type:feedexport/rule_condition_combine 
attribute:<nil> operator:<nil> value:1 is_value_processed:<nil> 
aggregator:any]]]

这是代码:

package main

import (
    "fmt"
    "github.com/wulijun/go-php-serialize/phpserialize"
)

func main() {
    rules := RulesList()
    for _, rule := range rules{
        fmt.Println(rule.Conditions.(interface{}))
    }
}

type Rule struct {
    RuleId     int         `json:"rule_id"`
    Conditions interface{} `json:"conditions"`
}

func RulesList() ([]Rule) {
    db := DbConn()
    res, err := db.Query(`SELECT r.rule_id, r.conditions_serialized AS 
    conditions FROM m_feedexport_rule AS r`)
    CheckError(err)
    rule  := Rule{}
    rules := []Rule{}
    for res.Next()  {
        var ruleId int
        var conditions string
        err = res.Scan(&ruleId, &conditions)
        CheckError(err)
        cons, err := phpserialize.Decode(conditions)
        CheckError(err)
        rule.RuleId     = ruleId
        rule.Conditions = cons   
        rules = append(rules, rule)
    }
    return rules
}

结果还可以,但我需要它的 map 形式,现在这是我无法循环的界面。 如果有人不理解代码,请问我。 非常感谢。

最佳答案

你是在谈论变量的类型cons,是吗?

背景

如果是,其类型为 interface{} 的原因是因为在 PHP 中,可以序列化任何类型的值(从裸整数到复杂对象),因此可以序列化任何反序列化代码必须应付它。由于在 Go 中所谓的“空接口(interface)”,interface{}, 任何类型都满足(包括程序员实现的任何自定义类型),PHP 序列化数据的解码器返回 interface{} 类型的值是明智的。

解决方案

确定解码成功后, 你需要 type-assert 结果值到您需要或使用的类型 一个type switch 根据具体类型进行发散处理 解码器返回的值。

该方法很好地展示了 你自己使用的包 test suite .

其中的一个片段展示了基本方法

if decodeRes, err = Decode(result); err != nil {
    t.Errorf("decode data fail %v, %v", err, result)
    return
}
decodeData, ok := decodeRes.(map[interface{}]interface{})
if !ok {
    t.Errorf("decode data type error, expected: map[interface{}]interface{}, get: %T", decodeRes)
    return
}
obj, _ := decodeData["object"].(*PhpObject)
if v, _ := obj.GetPrivateMemberValue("a"); v != int64(1) {
    t.Errorf("object private value expected 1, get %v, %T", v, v)
}
if v := obj.GetClassName(); v != "A" {
    t.Errorf("object class name expected A, get %v", v)
}

这里,decodeRes 是解码器返回的内容。 然后对该值进行类型断言以确保它是具体类型 (也称为“动态”——意思是“在运行时”)是 map [接口(interface){}]接口(interface){}

Note that the so-called "two-argument" type assert is used (it's also called a "comma-ok idiom") to not make the program panic at runtime in case the concrete type is different from the expected (always do this on data fetched from outside!).

类型断言的具体类型的值存储在 decodeData 变量,然后进一步检查该变量。

关于php - 迭代从 PHP 序列化格式解码的 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52538688/

相关文章:

php - 为什么 ë 百分比编码为 %EB 但也编码为 %C3%AB?

c# - JSON 反序列化对象

c# - 使用列表将 XML 反序列化为 C# 对象

Java - 在类上强制实例化

php - 如何在 php 中将一个表单元素值传递给下一个表单元素以进行 mysql 查询?

php - 使用 Ajax 和 PHP 更改下拉列表值

PHP rand 查询结果 - 检查新的随机查询与之前的不同

Golang 查询字符串作为查询的一部分

go - 有没有一种方法可以使用泛型确保传递的值具有某些字段?

go - 递归地将字符串附加到 slice 上会导致golang内存不足错误