]> granicus.if.org Git - php/commitdiff
Reenable __tostring() magic for print,echo,concatenation,function naming...
authorMarcus Boerger <helly@php.net>
Mon, 15 Dec 2003 16:59:21 +0000 (16:59 +0000)
committerMarcus Boerger <helly@php.net>
Mon, 15 Dec 2003 16:59:21 +0000 (16:59 +0000)
but not for other internal things.
# As discussed with Andi

Zend/zend.c
Zend/zend_object_handlers.c
Zend/zend_object_handlers.h
tests/classes/tostring.phpt

index 983d46e17b62d100bc8170e940eb229a5b5a14a5..5dbfb950da77961f3e036f3e4c6990b2ce14be3c 100644 (file)
@@ -227,7 +227,11 @@ ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_cop
                case IS_OBJECT:
                        if (expr->value.obj.handlers->cast_object) {
                                TSRMLS_FETCH();
-                               if (expr->value.obj.handlers->cast_object(expr, expr_copy, IS_STRING, 0 TSRMLS_CC) == SUCCESS) {
+                               if (expr->value.obj.handlers->cast_object == zend_std_cast_object) {
+                                       if (zend_std_cast_object_tostring(expr, expr_copy, IS_STRING, 0 TSRMLS_CC) == SUCCESS) {
+                                               break;
+                                       }
+                               } else if (expr->value.obj.handlers->cast_object(expr, expr_copy, IS_STRING, 0 TSRMLS_CC) == SUCCESS) {
                                        break;
                                }
                                if (EG(exception)) {
@@ -239,11 +243,6 @@ ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_cop
                        }
                        expr_copy->value.str.val = (char *) emalloc(sizeof("Object id #")-1 + MAX_LENGTH_OF_LONG);
                        expr_copy->value.str.len = sprintf(expr_copy->value.str.val, "Object id #%ld", (long)expr->value.obj.handle);
-#if 0
-                       /* FIXME: This might break BC for some people */
-                       expr_copy->value.str.len = sizeof("Object")-1;
-                       expr_copy->value.str.val = estrndup("Object", expr_copy->value.str.len);
-#endif
                        break;
                case IS_DOUBLE:
                        *expr_copy = *expr;
index f3ac745484f463a27e33785cc1c3400b278eb9e6..1528a3fda448a6b88096359770054c14b7eae3b3 100644 (file)
@@ -888,6 +888,40 @@ int zend_std_object_get_class_name(zval *object, char **class_name, zend_uint *c
        return SUCCESS;
 }
 
+ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC)
+{
+       zval fname, *retval;
+       int is_ref, refcount;
+       
+       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 (retval) {
+                                       if (Z_TYPE_P(retval) != IS_STRING) {
+                                               zend_error(E_ERROR, "Method %s::__toString() must return a string value", Z_OBJCE_P(readobj)->name);
+                                       }
+                               } else {
+                                       MAKE_STD_ZVAL(retval);
+                                       ZVAL_STRINGL(retval, empty_string, 0, 0);
+                               }
+                               zval_dtor(writeobj);
+                               is_ref = writeobj->is_ref;
+                               refcount = writeobj->refcount;
+                               *writeobj = *retval;
+                               zval_copy_ctor(writeobj);
+                               writeobj->is_ref = is_ref;
+                               writeobj->refcount = refcount;
+                               zval_ptr_dtor(&retval);
+                               return SUCCESS;
+                       }
+                       break;
+               default:
+                       break;
+       }
+       return FAILURE;
+}
+
 int zend_std_cast_object(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC)
 {
        return FAILURE;
index 3e98d7713b21e4b8473b0e11b3b9fe8f0f8f9963..9687f05f5ae5238092d7ce998a5744952cd27312 100644 (file)
@@ -118,6 +118,9 @@ union _zend_function *zend_std_get_static_method(zend_class_entry *ce, char *fun
 zval **zend_std_get_static_property(zend_class_entry *ce, char *property_name, int property_name_len, zend_bool silent TSRMLS_DC);
 zend_bool zend_std_unset_static_property(zend_class_entry *ce, char *property_name, int property_name_len TSRMLS_DC);
 
+int zend_std_cast_object(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC);
+ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC);
+
 
 #define IS_ZEND_STD_OBJECT(z)  ((z).type == IS_OBJECT && (Z_OBJ_HT((z))->get_class_entry != NULL))
 #define HAS_CLASS_ENTRY(z) (Z_OBJ_HT(z)->get_class_entry != NULL)
index 0f4c80517dfeb21836f825d2bb370aeb70417252..6aae0701354dd4a22063a7d2b570ae84173690c8 100644 (file)
@@ -10,7 +10,8 @@ class test1 {
 
 class test2 {
     function __toString() {
-        return "Converted";
+       echo __METHOD__ . "()\n";
+        return "Converted\n";
     }
 }
 
@@ -23,10 +24,26 @@ var_dump($o);
 echo "====test2====\n";
 $o = new test2;
 print_r($o);
-var_dump((string)$o);
+print $o;
 var_dump($o);
-echo "====done!====\n";
+echo "====test3====\n";
+echo $o;
+
+echo "====test4====\n";
+echo "string:".$o;
+
+echo "====test5====\n";
+echo 1 . $o;
+
+echo "====test6====\n";
+echo $o.$o;
+
+echo "====test7====\n";
+$ar = array();
+$ar[$o->__toString()] = "ERROR";
+echo $ar[$o];
 ?>
+====DONE!====
 --EXPECTF--
 ====test1====
 test1 Object
@@ -41,7 +58,26 @@ object(test1)#%d (0) {
 test2 Object
 (
 )
-string(9) "Converted"
+test2::__toString()
+Converted
 object(test2)#%d (0) {
 }
-====done!====
+====test3====
+test2::__toString()
+Converted
+====test4====
+test2::__toString()
+string:Converted
+====test5====
+test2::__toString()
+1Converted
+====test6====
+test2::__toString()
+test2::__toString()
+Converted
+Converted
+====test7====
+test2::__toString()
+
+Warning: Illegal offset type in %stostring.php on line %d
+====DONE!====