func ToFloat(zval *C.struct__zval_struct) float64 {
	return (float64)(C.value_get_double(zval))
}
Float returns the internal PHP value as a floating point number, converting
if necessary.
package engine
import "C"
import (
	"fmt"
	"strconv"
	"unsafe"
	"reflect"
)
type ValueKind int
const (
	IS_UNDEF ValueKind = 0
	IS_NULL ValueKind = 1
	IS_FALSE ValueKind = 2
	IS_TRUE ValueKind = 3
	IS_LONG ValueKind = 4
	IS_DOUBLE ValueKind = 5
	IS_STRING ValueKind = 6
	IS_ARRAY ValueKind = 7
	IS_OBJECT ValueKind = 8
	IS_RESOURCE ValueKind = 9
	IS_REFERENCE ValueKind = 10
)
func NewValue(val interface{}) (*C.struct__zval_struct, error) {
	zval, err := C.value_new()
	if err != nil {
		return &zval, fmt.Errorf("Unable to instantiate PHP value")
	}
	v := reflect.ValueOf(val)
	switch v.Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		C.value_set_long(&zval, C.long(v.Int()))
	case reflect.Float32, reflect.Float64:
		C.value_set_double(&zval, C.double(v.Float()))
	case reflect.Bool:
		C.value_set_bool(&zval, C.bool(v.Bool()))
	case reflect.String:
		str := C.CString(v.String())
		defer C.free(unsafe.Pointer(str))
		C.value_set_string(&zval, str)
	case reflect.Slice:
		C.value_set_array(&zval, C.uint(v.Len()))
		for i := 0; i < v.Len(); i++ {
			vs, err := NewValue(v.Index(i).Interface())
			if err != nil {
				C._value_destroy(&zval)
				return nil, err
			}
			C.value_array_next_set(&zval, vs)
		}
	case reflect.Map:
		kt := v.Type().Key().Kind()
		if kt == reflect.Int || kt == reflect.String {
			C.value_set_array(&zval, C.uint(v.Len()))
			for _, key := range v.MapKeys() {
				kv, err := NewValue(v.MapIndex(key).Interface())
				if err != nil {
					C._value_destroy(&zval)
					return nil, err
				}
				if kt == reflect.Int {
					C.value_array_index_set(&zval, C.ulong(key.Int()), kv)
				} else {
					str := C.CString(key.String())
					C.value_array_key_set(&zval, str, kv)
					C.free(unsafe.Pointer(str))
				}
			}
		} else {
			return nil, fmt.Errorf("Unable to create value of unknown type '%T'", val)
		}
	case reflect.Struct:
		C.value_set_object(&zval)
		vt := v.Type()
		for i := 0; i < v.NumField(); i++ {
			if vt.Field(i).PkgPath != "" {
				continue
			}
			fv, err := NewValue(v.Field(i).Interface())
			if err != nil {
				C._value_destroy(&zval)
				return nil, err
			}
			str := C.CString(vt.Field(i).Name)
			C.value_object_property_set(&zval, str, fv)
			C.free(unsafe.Pointer(str))
			DestroyValue(fv)
		}
	case reflect.Invalid:
		C.value_set_null(&zval)
	default:
		C._value_destroy(&zval)
		return nil, fmt.Errorf("Unable to create value of unknown type '%T'", val)
	}
	return &zval, nil
}
func IsNull(zval *C.struct__zval_struct) bool {
	return zval == nil || GetKind(zval) == IS_NULL
}
func GetKind(zval *C.struct__zval_struct) ValueKind {
	return (ValueKind)(C.value_kind(zval))
}
func ToInterface(zval *C.struct__zval_struct) interface{} {
	switch GetKind(zval) {
	case IS_LONG:
		return ToInt(zval)
	case IS_DOUBLE:
		return ToFloat(zval)
	case IS_TRUE:
		return true
	case IS_FALSE:
		return false
	case IS_STRING:
		return ToString(zval)
	case IS_ARRAY:
		if C.value_array_is_associative(zval) {
			return ToMap(zval)
		} else {
			return ToSlice(zval)
		}
	case IS_OBJECT:
		return ToMap(zval)
	}
	return nil
}
func ToInt(zval *C.struct__zval_struct) int64 {
	return (int64)(C.value_get_long(zval))
}