summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Boerger <helly@php.net>2003-09-18 11:38:33 +0000
committerMarcus Boerger <helly@php.net>2003-09-18 11:38:33 +0000
commitd7fdf15a413de33953a2060b22c58b87f2f06abb (patch)
treefaf00211c24f74a772ca6dff1a33fefd8f9bbc05
parent87045df4ce1137b7604ed9a767b78eeaebe79b5e (diff)
downloadphp-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.c24
-rw-r--r--Zend/zend_object_handlers.h2
-rw-r--r--Zend/zend_operators.c16
-rw-r--r--tests/classes/tostring.phpt47
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!====