cvs: ZendEngine2 / zend.c zend_object_handlers.c zend_object_handlers.h php-src/tests/classes tostring.phpt
| From: | Marcus Boerger | Date: | Mon, 15 Dec 2003 16:59:21 +0000 |
| Subject: | cvs: ZendEngine2 / zend.c zend_object_handlers.c zend_object_handlers.h php-src/tests/classes tostring.phpt | ||
| Groups: | php.zend-engine.cvs | ||
| Request: | Send a blank email to php-zend-engine-cvs+get-2120@lists.php.net to get a copy of this message | ||
helly Mon Dec 15 11:59:21 2003 EDT
Modified files:
/php-src/tests/classes tostring.phpt
/ZendEngine2 zend.c zend_object_handlers.c zend_object_handlers.h
Log:
Reenable __tostring() magic for print,echo,concatenation,function naming...
but not for other internal things.
# As discussed with Andi
Index: php-src/tests/classes/tostring.phpt
diff -u php-src/tests/classes/tostring.phpt:1.1 php-src/tests/classes/tostring.phpt:1.2
--- php-src/tests/classes/tostring.phpt:1.1 Thu Sep 18 07:38:32 2003
+++ php-src/tests/classes/tostring.phpt Mon Dec 15 11:59:20 2003
@@ -10,7 +10,8 @@
class test2 {
function __toString() {
- return "Converted";
+ echo __METHOD__ . "()\n";
+ return "Converted\n";
}
}
@@ -23,10 +24,26 @@
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 @@
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!====
Index: ZendEngine2/zend.c
diff -u ZendEngine2/zend.c:1.258 ZendEngine2/zend.c:1.259
--- ZendEngine2/zend.c:1.258 Fri Dec 12 06:14:44 2003
+++ ZendEngine2/zend.c Mon Dec 15 11:59:21 2003
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend.c,v 1.258 2003/12/12 11:14:44 helly Exp $ */
+/* $Id: zend.c,v 1.259 2003/12/15 16:59:21 helly Exp $ */
#include "zend.h"
#include "zend_extensions.h"
@@ -227,7 +227,11 @@
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 @@
}
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: ZendEngine2/zend_object_handlers.c
diff -u ZendEngine2/zend_object_handlers.c:1.80 ZendEngine2/zend_object_handlers.c:1.81
--- ZendEngine2/zend_object_handlers.c:1.80 Thu Dec 11 04:56:06 2003
+++ ZendEngine2/zend_object_handlers.c Mon Dec 15 11:59:21 2003
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_object_handlers.c,v 1.80 2003/12/11 09:56:06 helly Exp $ */
+/* $Id: zend_object_handlers.c,v 1.81 2003/12/15 16:59:21 helly Exp $ */
#include "zend.h"
#include "zend_globals.h"
@@ -888,6 +888,40 @@
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: ZendEngine2/zend_object_handlers.h
diff -u ZendEngine2/zend_object_handlers.h:1.26 ZendEngine2/zend_object_handlers.h:1.27
--- ZendEngine2/zend_object_handlers.h:1.26 Mon Nov 10 11:14:44 2003
+++ ZendEngine2/zend_object_handlers.h Mon Dec 15 11:59:21 2003
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_object_handlers.h,v 1.26 2003/11/10 16:14:44 helly Exp $ */
+/* $Id: zend_object_handlers.h,v 1.27 2003/12/15 16:59:21 helly Exp $ */
#ifndef ZEND_OBJECT_HANDLERS_H
#define ZEND_OBJECT_HANDLERS_H
@@ -118,6 +118,9 @@
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)