为了账号安全,请及时绑定邮箱和手机立即绑定

在goland反序列化php

在goland反序列化php

Go
慕标琳琳 2022-11-08 16:33:11
我在 PHP 中有一个带有序列化数组的文件。文件的内容像这样锁定a:2:{i:250;s:7:"my_catz";s:7:"abcd.jp";a:2:{s:11:"category_id";i:250;s:13:"category_name";s:7:"my_catz";}}未序列化的数组是这个(    [250] => my_catz    [abcd.jp] => Array        (            [category_id] => 250            [category_name] => my_catz        ))现在,我想在 GO 中获取文件的内容,将其反序列化并将其转换为数组。在 GO 中,我可以使用dat, err := os.ReadFile("/etc/squid3/compiled-categories.db")    if err != nil {        if e.Debug {            log.Printf("error reading /etc/squid3/compiled-categories.db: ", err)        }    }并使用 github.com/techoner/gophp 库对其进行反序列化package categorizationimport (      "fmt"    "os"    "github.com/techoner/gophp"    "log"    "errors")type Data struct {      Website   string    Debug   bool}func (e Data) CheckPersonalCategories() (int,string) {      if e.Debug {        log.Printf("Checking Personal Categories")    }    if _, err := os.Stat("/etc/squid3/compiled-categories.db"); errors.Is(err, os.ErrNotExist) {        if e.Debug {            log.Printf("/etc/squid3/compiled-categories.db not exit: ", err)        }        return  0,""    }    dat, err := os.ReadFile("/etc/squid3/compiled-categories.db")    if err != nil {        if e.Debug {            log.Printf("error reading /etc/squid3/compiled-categories.db: ", err)        }    }        out, _ := gophp.Unserialize(dat)        fmt.Println(out["abcd.jp"])return  0,""}但我无法访问数组,例如,当我尝试使用 out["abcd.jp"] 访问数组键时,我收到此错误消息invalid operation: out["abcd.jp"] (type interface {} does not support indexing)out的结果是map[250:my_catz abcd.jp:map[category_id:250 category_name:my_catz]]
查看完整描述

1 回答

?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

正在反序列化的接缝

不要对代码中的成功和失败做出假设。错误响应是了解函数是否成功的唯一可靠方法。在这种情况下,假设可能成立,但忽略错误始终是错误的。花时间捕捉错误,至少panic是它们——不要浪费时间忽略错误,然后尝试调试不可靠的代码。

无效操作:out["abcd.jp"](类型接口{}不支持索引)

不幸的是,您使用的包没有提供任何文档,因此您必须阅读源代码才能了解gophp.Unserialize返回(interface{}, error)。这是有道理的;php可以序列化任何值,所以Unserialize必须能够返回任何值。

out因此,interface{}它的基础价值取决于数据。要将 ainterface{}转换为特定值需要类型断言。在这种情况下,我们认为基础数据应该是map[string]interface{}. 所以我们需要做一个类型断言:

mout, ok := out.(map[string]interface{})

在我们讨论工作代码之前,我希望您再考虑一点。看下面的代码:我是从你的代码开始的,但相似之处非常轻微。我取出了几乎所有代码,因为它与您的问题完全无关。我将输入数据添加到代码中,以尽可能少地复制您的代码(正如我要求您这样做而您拒绝这样做)。这是对您时间的一种很好的利用,原因有两个:首先,它使您更容易获得答案(既因为它表明您付出了足够的努力,也因为它简化了对问题的描述),其次,因为它是调试的绝佳实践。我一直对代码流进行最少的复制,以更好地理解如何做事。

您会注意到您现在可以运行此代码而无需任何额外的努力。这是提供最小可重现示例的正确方法——而不是使用一大块仍然无法由任何人执行的几乎不相关的代码。

Go Plaground 是演示其他人可以执行和调查的特定于 go 的代码的好方法。您还可以在https://go.dev/play/p/QfCl08Gx53e看到下面的代码

package main


import (

    "fmt"


    "github.com/techoner/gophp"

)


type Data struct {

    Website string

    Debug   bool

}


func main() {

    var dat = []byte(`a:2:{i:250;s:7:"my_catz";s:7:"abcd.jp";a:2:{s:11:"category_id";i:250;s:13:"category_name";s:7:"my_catz";}}`)

    out, err := gophp.Unserialize(dat)

    if err != nil {

        panic(err)

    }

    if mout, ok := out.(map[string]interface{}); ok {

        fmt.Println(mout["abcd.jp"])

    }

}


查看完整回答
反对 回复 2022-11-08
  • 1 回答
  • 0 关注
  • 70 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信