package php // #include // #include "zval.h" import "C" import ( "fmt" "reflect" ) type Value any func go_to_zval(value Value) *C.zval { zval := C.new_zval() v := reflect.ValueOf(value) switch v.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: C.zval_set_long(&zval, C.long(v.Int())) } return &zval } func zval_array_to_go(array *C.zend_array) map[string]Value { var pos C.HashPosition var entry C.hash_table_entry C.zend_array_init_traverse(array, &pos) ret := map[string]Value{} for C.zend_array_get_next(array, &pos, &entry) != 0 { var key string switch entry.key_type { case C.HASH_KEY_IS_STRING: key = C.GoString(C.zend_string_cstr(entry.key_str)) case C.HASH_KEY_IS_LONG: key = fmt.Sprintf("%d", entry.key_long) } ret[key] = zval_to_go(entry.value) } return ret } func zval_to_go(val C.zval) Value { switch C.zval_get_type(&val) { case C.IS_LONG: // All integers return C.zval_get_long(&val) case C.IS_DOUBLE: // Floating points return C.zval_get_double(&val) case C.IS_STRING: zstr := C.zval_get_string(&val) if zstr != nil { str := C.GoString(C.zend_string_cstr(zstr)) C.zend_string_release(zstr) return str } case C.IS_ARRAY: return zval_array_to_go(C.zval_get_array(&val)) } return nil }