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 | |
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.
-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 | ||||
-rw-r--r-- | tests/classes/tostring.phpt | 47 |
4 files changed, 82 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); diff --git a/tests/classes/tostring.phpt b/tests/classes/tostring.phpt new file mode 100644 index 0000000000..0f4c80517d --- /dev/null +++ b/tests/classes/tostring.phpt @@ -0,0 +1,47 @@ +--TEST-- +ZE2 __toString() +--SKIPIF-- +<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 needed'); ?> +--FILE-- +<?php + +class test1 { +} + +class test2 { + function __toString() { + return "Converted"; + } +} + +echo "====test1====\n"; +$o = new test1; +print_r($o); +var_dump((string)$o); +var_dump($o); + +echo "====test2====\n"; +$o = new test2; +print_r($o); +var_dump((string)$o); +var_dump($o); +echo "====done!====\n"; +?> +--EXPECTF-- +====test1==== +test1 Object +( +) + +Notice: Object of class test1 could not be converted to string in %stostring.php on line %d +string(6) "Object" +object(test1)#%d (0) { +} +====test2==== +test2 Object +( +) +string(9) "Converted" +object(test2)#%d (0) { +} +====done!==== |