mirror of
https://github.com/deuill/go-php.git
synced 2024-09-21 00:40:45 +00:00
Add struct-to-object value bindings
This commit is contained in:
parent
7ed2c81ec6
commit
6a3fd786ea
17
php_test.go
17
php_test.go
@ -120,12 +120,29 @@ var bindTests = []struct {
|
|||||||
value interface{} // Value to bind
|
value interface{} // Value to bind
|
||||||
expected string // Serialized form of value
|
expected string // Serialized form of value
|
||||||
}{
|
}{
|
||||||
|
// Integer to integer.
|
||||||
{42, "i:42;"},
|
{42, "i:42;"},
|
||||||
|
// Float to double.
|
||||||
{3.14159, "d:3.1415899999999999;"},
|
{3.14159, "d:3.1415899999999999;"},
|
||||||
|
// Boolean to boolean.
|
||||||
{true, "b:1;"},
|
{true, "b:1;"},
|
||||||
|
// String to string.
|
||||||
{"Such bind", `s:9:"Such bind";`},
|
{"Such bind", `s:9:"Such bind";`},
|
||||||
|
// Simple slice of strings to indexed array.
|
||||||
{[]string{"this", "that"}, `a:2:{i:0;s:4:"this";i:1;s:4:"that";}`},
|
{[]string{"this", "that"}, `a:2:{i:0;s:4:"this";i:1;s:4:"that";}`},
|
||||||
|
// Nested slice of integers to indexed array.
|
||||||
{[][]int{[]int{1, 2}, []int{3}}, `a:2:{i:0;a:2:{i:0;i:1;i:1;i:2;}i:1;a:1:{i:0;i:3;}}`},
|
{[][]int{[]int{1, 2}, []int{3}}, `a:2:{i:0;a:2:{i:0;i:1;i:1;i:2;}i:1;a:1:{i:0;i:3;}}`},
|
||||||
|
// Struct to object, with nested struct.
|
||||||
|
{struct {
|
||||||
|
I int
|
||||||
|
C string
|
||||||
|
F struct {
|
||||||
|
G bool
|
||||||
|
}
|
||||||
|
h bool
|
||||||
|
}{3, "test", struct {
|
||||||
|
G bool
|
||||||
|
}{false}, true}, `O:8:"stdClass":3:{s:1:"I";i:3;s:1:"C";s:4:"test";s:1:"F";O:8:"stdClass":1:{s:1:"G";b:0;}}`},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContextBind(t *testing.T) {
|
func TestContextBind(t *testing.T) {
|
||||||
|
@ -62,6 +62,19 @@ void value_array_set_key(void *arr, const char *key, void *val) {
|
|||||||
add_assoc_zval((zval *) arr, key, (zval *) val);
|
add_assoc_zval((zval *) arr, key, (zval *) val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *value_create_object() {
|
||||||
|
zval *v;
|
||||||
|
|
||||||
|
MAKE_STD_ZVAL(v);
|
||||||
|
object_init(v);
|
||||||
|
|
||||||
|
return (void *) v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void value_object_add_property(void *obj, const char *key, void *val) {
|
||||||
|
add_property_zval((zval *) obj, key, (zval *) val);
|
||||||
|
}
|
||||||
|
|
||||||
void value_destroy(void *zvalptr) {
|
void value_destroy(void *zvalptr) {
|
||||||
zval_dtor((zval *) zvalptr);
|
zval_dtor((zval *) zvalptr);
|
||||||
}
|
}
|
@ -53,9 +53,10 @@ func (v *Value) Destroy() {
|
|||||||
// map[int|string] -> associative array
|
// map[int|string] -> associative array
|
||||||
// struct -> object
|
// struct -> object
|
||||||
//
|
//
|
||||||
// Bindings for functions and method receivers to PHP functions and classes are
|
// It is only possible to bind maps with integer or string keys. Only exported
|
||||||
// only available in the engine scope, and must be predeclared before context
|
// struct fields are passed to the PHP context. Bindings for functions and method
|
||||||
// execution.
|
// receivers to PHP functions and classes are only available in the engine scope,
|
||||||
|
// and must be predeclared before context execution.
|
||||||
func New(val interface{}) (*Value, error) {
|
func New(val interface{}) (*Value, error) {
|
||||||
var ptr unsafe.Pointer
|
var ptr unsafe.Pointer
|
||||||
|
|
||||||
@ -74,9 +75,9 @@ func New(val interface{}) (*Value, error) {
|
|||||||
// Bind string to PHP string type.
|
// Bind string to PHP string type.
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
str := C.CString(v.String())
|
str := C.CString(v.String())
|
||||||
defer C.free(unsafe.Pointer(str))
|
|
||||||
|
|
||||||
ptr = C.value_create_string(str)
|
ptr = C.value_create_string(str)
|
||||||
|
C.free(unsafe.Pointer(str))
|
||||||
// Bind slice to PHP indexed array type.
|
// Bind slice to PHP indexed array type.
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
ptr = C.value_create_array(C.uint(v.Len()))
|
ptr = C.value_create_array(C.uint(v.Len()))
|
||||||
@ -84,6 +85,7 @@ func New(val interface{}) (*Value, error) {
|
|||||||
for i := 0; i < v.Len(); i++ {
|
for i := 0; i < v.Len(); i++ {
|
||||||
vs, err := New(v.Index(i).Interface())
|
vs, err := New(v.Index(i).Interface())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
C.value_destroy(ptr)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,6 +101,7 @@ func New(val interface{}) (*Value, error) {
|
|||||||
for _, key := range v.MapKeys() {
|
for _, key := range v.MapKeys() {
|
||||||
kv, err := New(v.MapIndex(key).Interface())
|
kv, err := New(v.MapIndex(key).Interface())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
C.value_destroy(ptr)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +117,28 @@ func New(val interface{}) (*Value, error) {
|
|||||||
} else {
|
} else {
|
||||||
return nil, errInvalidType
|
return nil, errInvalidType
|
||||||
}
|
}
|
||||||
|
// Bind struct to PHP object (stdClass) type.
|
||||||
|
case reflect.Struct:
|
||||||
|
vt := v.Type()
|
||||||
|
ptr = C.value_create_object()
|
||||||
|
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
// Skip unexported fields.
|
||||||
|
if vt.Field(i).PkgPath != "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fv, err := New(v.Field(i).Interface())
|
||||||
|
if err != nil {
|
||||||
|
C.value_destroy(ptr)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
str := C.CString(vt.Field(i).Name)
|
||||||
|
|
||||||
|
C.value_object_add_property(ptr, str, fv.Ptr())
|
||||||
|
C.free(unsafe.Pointer(str))
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return nil, errInvalidType
|
return nil, errInvalidType
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ void *value_create_string(char *value);
|
|||||||
void *value_create_array(unsigned int size);
|
void *value_create_array(unsigned int size);
|
||||||
void value_array_set_index(void *arr, unsigned long idx, void *val);
|
void value_array_set_index(void *arr, unsigned long idx, void *val);
|
||||||
void value_array_set_key(void *arr, const char *key, void *val);
|
void value_array_set_key(void *arr, const char *key, void *val);
|
||||||
|
void *value_create_object();
|
||||||
|
void value_object_add_property(void *obj, const char *key, void *val);
|
||||||
void value_destroy(void *zvalptr);
|
void value_destroy(void *zvalptr);
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue
Block a user