diff options
| author | Marcus Boerger <helly@php.net> | 2003-09-18 11:38:33 +0000 |
|---|---|---|
| committer | Marcus Boerger <helly@php.net> | 2003-09-18 11:38:33 +0000 |
| commit | d7fdf15a413de33953a2060b22c58b87f2f06abb (patch) | |
| tree | faf00211c24f74a772ca6dff1a33fefd8f9bbc05 /Zend | |
| parent | 87045df4ce1137b7604ed9a767b78eeaebe79b5e (diff) | |
| download | php-git-d7fdf15a413de33953a2060b22c58b87f2f06abb.tar.gz | |
- Allow partial type conversion support for objects.
- Add support for object to string conversion from userspace by method
__toString() and add a test.
Diffstat (limited to 'Zend')
| -rw-r--r-- | Zend/zend_object_handlers.c | 24 | ||||
| -rw-r--r-- | Zend/zend_object_handlers.h | 2 | ||||
| -rw-r--r-- | Zend/zend_operators.c | 16 |
3 files changed, 35 insertions, 7 deletions
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 30b02ad95d..86b0ea2dd3 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -860,6 +860,28 @@ int zend_std_object_get_class_name(zval *object, char **class_name, zend_uint *c return SUCCESS; } +int zend_std_cast_object(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC) +{ + zval fname, *retval; + + switch (type) { + case IS_STRING: + ZVAL_STRING(&fname, "__tostring", 0); + if (call_user_function_ex(NULL, &readobj, &fname, &retval, 0, NULL, 0, NULL TSRMLS_CC) == SUCCESS) { + if (Z_TYPE_P(retval) != IS_STRING) { + zend_error(E_ERROR, "Method %s::__toString() must return a string value", Z_OBJCE_P(readobj)->name); + } + ZVAL_STRING(writeobj, Z_STRVAL_P(retval), 1); + zval_ptr_dtor(&retval); + return SUCCESS; + } + break; + default: + break; + } + return FAILURE; +} + zend_object_handlers std_object_handlers = { zend_objects_store_add_ref, /* add_ref */ zend_objects_store_del_ref, /* del_ref */ @@ -884,7 +906,7 @@ zend_object_handlers std_object_handlers = { zend_std_object_get_class, /* get_class_entry */ zend_std_object_get_class_name, /* get_class_name */ zend_std_compare_objects, /* compare_objects */ - NULL, /* cast_object */ + zend_std_cast_object, /* cast_object */ }; /* diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index eb8538e495..503f153e2f 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -82,7 +82,7 @@ typedef zend_object_value (*zend_object_clone_obj_t)(zval *object TSRMLS_DC); typedef zend_class_entry *(*zend_object_get_class_entry_t)(zval *object TSRMLS_DC); typedef int (*zend_object_get_class_name_t)(zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC); typedef int (*zend_object_compare_t)(zval *object1, zval *object2 TSRMLS_DC); -typedef void (*zend_object_cast_t)(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC); +typedef int (*zend_object_cast_t)(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC); typedef struct _zend_object_handlers { diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 257ea583e0..8f3b73fcdc 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -488,14 +488,20 @@ ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) break; case IS_OBJECT: if (op->value.obj.handlers->cast_object) { + zval tmp; TSRMLS_FETCH(); - op->value.obj.handlers->cast_object(op, op, IS_STRING, 1 TSRMLS_CC); + if (op->value.obj.handlers->cast_object(op, &tmp, IS_STRING, 1 TSRMLS_CC) == SUCCESS) { + zval_dtor(op); + *op = tmp; + break; + } + zend_error(E_NOTICE, "Object of class %s could not be converted to string", Z_OBJCE_P(op)->name); } else { - zval_dtor(op); - op->value.str.val = estrndup_rel("Object", sizeof("Object")-1); - op->value.str.len = sizeof("Object")-1; - zend_error(E_NOTICE, "Object to string conversion"); + zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name); } + zval_dtor(op); + op->value.str.val = estrndup_rel("Object", sizeof("Object")-1); + op->value.str.len = sizeof("Object")-1; break; default: zval_dtor(op); |
