Penyunting PHP Strawberry Pengenalan: YAML ialah format siri data yang ringan Ia mempunyai sintaks yang ringkas dan mudah dibaca dan digunakan secara meluas untuk fail konfigurasi dan pertukaran data. Dalam PHP, kita boleh menggunakan perpustakaan penghuraian YAML untuk menyahmarshal data YAML ke dalam objek kompleks, yang boleh menjadi struktur atau rentetan. Ini memberikan pembangun cara yang mudah untuk mengendalikan dan memanipulasi fail konfigurasi dan data lain. Sama ada membina aplikasi kompleks atau memudahkan pengurusan konfigurasi, penghuraian YAML memainkan peranan penting dalam PHP.
Cuba unmarshal yaml menjadi objek kompleks, seperti map[string]map[interface{}]string
.
Masalahnya ialah saya ingin dapat membezakan bahagian string
和 source
之间的 interface{}
iaitu struktur.
type source struct { id string `yaml:"id"` name string `yaml:"name"` logoid string `yaml:"logoid"` url string `yaml:"url"` } type unft struct { itemmeta map[string]map[interface{}]string `yaml:"item_meta"` // could be // itemmeta map[string]map[string]string `yaml:"item_meta"` // or // itemmeta map[string]map[source]string `yaml:"item_meta"` }
Nampaknya yaml tidak tahu bagaimana untuk membuka source
结构中,所以我必须实现 unmarshaler
antara muka:
type unmarshaler interface { unmarshalyaml(value *node) error }
Tetapi saya tidak begitu memahami keadaan keseluruhan proses unmarshalling. Secara umum, saya menganggap saya perlu mengulang *yaml.node
并在每个节点上调用 func unmarshalyaml(value *node) error
secara manual.
package main import ( "fmt" "gopkg.in/yaml.v3" ) type Source struct { ID string `json:"id"` Name string `json:"name"` LogoID string `json:"logoId"` URL string `json:"url"` } var data = ` unf: item_meta: source: !struct ? id: "data-watch" name: "DataWatch" logoid: "data-watch" url: "https" : "product_any('SS')" public_usage: "": "source_any('SDF')" "provider": "source_any('ANO')"` type UNFT struct { ItemMeta map[string]map[interface{}]string `yaml:"item_meta"` } type MetaConverterConfigT struct { UNFT UNFT `yaml:"unf"` } func main() { cfg := MetaConverterConfigT{} err := yaml.Unmarshal([]byte(data), &cfg) if err != nil { fmt.Println("%w", err) } fmt.Println(cfg) } func (s *UNFT) UnmarshalYAML(n *yaml.Node) error { var cfg map[string]map[interface{}]string if err := n.Decode(&cfg); err != nil { fmt.Println("%w", err) } return nil }
Pergi ke taman hiburan
type metakey struct { string string source source } func (k *metakey) unmarshalyaml(n *yaml.node) error { if n.tag == "!!str" { return n.decode(&k.string) } if n.tag == "!!map" { return n.decode(&k.source) } return fmt.errorf("unsupported metakey type") } // ... type unft struct { itemmeta map[string]map[metakey]string `yaml:"item_meta"` }
https://www.php.cn/link/50f9999b2ee27e222c5513e945e9ea9c
Jika anda perlu mengekalkan jenis yang dipetakan tidak berubah, iaitu tanpa menambah jenis kunci tersuai, maka anda juga boleh melaksanakan unmarshaller pada unft dan hanya memetakan semula menggunakan any
:
type UNFT struct { ItemMeta map[string]map[any]string `yaml:"item_meta"` } func (u *UNFT) UnmarshalYAML(n *yaml.Node) error { var obj struct { ItemMeta map[string]map[MetaKey]string `yaml:"item_meta"` } if err := n.Decode(&obj); err != nil { return err } u.ItemMeta = make(map[string]map[any]string, len(obj.ItemMeta)) for k, v := range obj.ItemMeta { m := make(map[any]string, len(v)) for k, v := range v { if k.Source != (Source{}) { m[k.Source] = v } else { m[k.String] = v } } u.ItemMeta[k] = m } return nil }
https://www.php.cn/link/543378fb36a83810ded2d725f2b6c883
Atas ialah kandungan terperinci Unmarshal YAML menjadi objek kompleks, sama ada struct atau rentetan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!