我在 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 categorization
import (
"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]]
uj5u.com熱心網友回復:
正在反序列化的接縫
不要對代碼中的成功和失敗做出假設。錯誤回應是了解函式是否成功的唯一可靠方法。在這種情況下,假設可能成立,但忽略錯誤始終是錯誤的。花時間捕捉錯誤,至少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"])
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/429837.html
上一篇:golangtabwriter列印垃圾并且格式不正確
下一篇: 是 =1的語法糖嗎?
