felipe Fri, 07 May 2010 13:55:27 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=299102
Log: - Fixed magic method and constructor copy for traits Changed paths: A php/php-src/trunk/Zend/tests/traits/methods_001.phpt A php/php-src/trunk/Zend/tests/traits/methods_002.phpt A php/php-src/trunk/Zend/tests/traits/methods_003.phpt U php/php-src/trunk/Zend/zend_compile.c Added: php/php-src/trunk/Zend/tests/traits/methods_001.phpt =================================================================== --- php/php-src/trunk/Zend/tests/traits/methods_001.phpt (rev 0) +++ php/php-src/trunk/Zend/tests/traits/methods_001.phpt 2010-05-07 13:55:27 UTC (rev 299102) @@ -0,0 +1,39 @@ +--TEST-- +Testing magic method on trait +--FILE-- +<?php + +trait foo { + public function __toString() { + return '123'; + } + + public function __get($x) { + var_dump($x); + } + + public function __set($attr, $val) { + var_dump($attr .'==='. $val); + } + + public function __clone() { + var_dump(__FUNCTION__); + } +} + +class bar { + use foo; +} + +$o = new bar; +echo $o, PHP_EOL; +$o->xyz; +$o->xyz = 2; +clone $o; + +?> +--EXPECT-- +123 +string(3) "xyz" +string(7) "xyz===2" +string(7) "__clone" Property changes on: php/php-src/trunk/Zend/tests/traits/methods_001.phpt ___________________________________________________________________ Added: svn:keywords + Id Rev Revision Added: svn:eol-style + native Added: php/php-src/trunk/Zend/tests/traits/methods_002.phpt =================================================================== --- php/php-src/trunk/Zend/tests/traits/methods_002.phpt (rev 0) +++ php/php-src/trunk/Zend/tests/traits/methods_002.phpt 2010-05-07 13:55:27 UTC (rev 299102) @@ -0,0 +1,30 @@ +--TEST-- +Testing collision with magic methods +--FILE-- +<?php + +trait foo { + public function __clone() { + var_dump(__FUNCTION__); + } +} + +trait baz { + public function __clone() { + var_dump(__FUNCTION__); + } +} + +class bar { + use foo; + use baz; +} + +$o = new bar; +var_dump(clone $o); + +?> +--EXPECTF-- +Warning: Trait method __clone has not been applied, because there are collisions with other trait methods on bar in %s on line %d +object(bar)#%d (0) { +} Property changes on: php/php-src/trunk/Zend/tests/traits/methods_002.phpt ___________________________________________________________________ Added: svn:keywords + Id Rev Revision Added: svn:eol-style + native Added: php/php-src/trunk/Zend/tests/traits/methods_003.phpt =================================================================== --- php/php-src/trunk/Zend/tests/traits/methods_003.phpt (rev 0) +++ php/php-src/trunk/Zend/tests/traits/methods_003.phpt 2010-05-07 13:55:27 UTC (rev 299102) @@ -0,0 +1,24 @@ +--TEST-- +Testing __construct and __destruct with Trait +--FILE-- +<?php + +trait foo { + public function __construct() { + var_dump(__FUNCTION__); + } + public function __destruct() { + var_dump(__FUNCTION__); + } +} + +class bar { + use foo; +} + +new bar; + +?> +--EXPECT-- +string(11) "__construct" +string(10) "__destruct" Property changes on: php/php-src/trunk/Zend/tests/traits/methods_003.phpt ___________________________________________________________________ Added: svn:keywords + Id Rev Revision Added: svn:eol-style + native Modified: php/php-src/trunk/Zend/zend_compile.c =================================================================== --- php/php-src/trunk/Zend/zend_compile.c 2010-05-07 13:31:13 UTC (rev 299101) +++ php/php-src/trunk/Zend/zend_compile.c 2010-05-07 13:55:27 UTC (rev 299102) @@ -3329,16 +3329,18 @@ strncmp(mname, str, mname_len) #define _ADD_MAGIC_METHOD(ce, mname, mname_len, fe) { \ - if (IS_EQUAL(mname, mname_len, "__clone")) { (ce)->clone = (fe); (fe)->common.fn_flags = ZEND_ACC_CLONE; } \ - else if (IS_EQUAL(mname, mname_len, "__get")) (ce)->__get = (fe); \ - else if (IS_EQUAL(mname, mname_len, "__set")) (ce)->__set = (fe); \ - else if (IS_EQUAL(mname, mname_len, "__call")) (ce)->__call = (fe); \ - else if (IS_EQUAL(mname, mname_len, "__unset")) (ce)->__unset = (fe); \ - else if (IS_EQUAL(mname, mname_len, "__isset")) (ce)->__isset = (fe); \ - else if (IS_EQUAL(mname, mname_len, "__callstatic"))(ce)->__callstatic = (fe); \ - else if (IS_EQUAL(mname, mname_len, "__tostring")) (ce)->__tostring = (fe); \ - else if (IS_EQUAL(mname, mname_len, "serialize_func")) (ce)->serialize_func = (fe); \ - else if (IS_EQUAL(mname, mname_len, "unserialize_func"))(ce)->unserialize_func = (fe); \ + if (!IS_EQUAL(mname, mname_len, "__clone")) { (ce)->clone = (fe); (fe)->common.fn_flags |= ZEND_ACC_CLONE; } \ + else if (!IS_EQUAL(mname, mname_len, "__construct")) { (ce)->constructor = (fe); (fe)->common.fn_flags |= ZEND_ACC_CTOR; } \ + else if (!IS_EQUAL(mname, mname_len, "__destruct")) { (ce)->destructor = (fe); (fe)->common.fn_flags |= ZEND_ACC_DTOR; } \ + else if (!IS_EQUAL(mname, mname_len, "__get")) (ce)->__get = (fe); \ + else if (!IS_EQUAL(mname, mname_len, "__set")) (ce)->__set = (fe); \ + else if (!IS_EQUAL(mname, mname_len, "__call")) (ce)->__call = (fe); \ + else if (!IS_EQUAL(mname, mname_len, "__unset")) (ce)->__unset = (fe); \ + else if (!IS_EQUAL(mname, mname_len, "__isset")) (ce)->__isset = (fe); \ + else if (!IS_EQUAL(mname, mname_len, "__callstatic"))(ce)->__callstatic = (fe); \ + else if (!IS_EQUAL(mname, mname_len, "__tostring")) (ce)->__tostring = (fe); \ + else if (!IS_EQUAL(mname, mname_len, "serialize_func")) (ce)->serialize_func = (fe); \ + else if (!IS_EQUAL(mname, mname_len, "unserialize_func"))(ce)->unserialize_func = (fe); \ } /* {{{ Originates from php_runkit_function_copy_ctor @@ -3433,6 +3435,7 @@ zend_class_entry *ce = va_arg(args, zend_class_entry*); int add = 0; zend_function* existing_fn; + zend_function fn_copy, *fn_copy_p; zend_function* prototype = NULL; /* is used to determine the prototype according to the inheritance chain */ if (zend_hash_quick_find(&ce->function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void**) &existing_fn) == FAILURE) { @@ -3472,17 +3475,20 @@ if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) { ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS; } + fn_copy = *fn; + zend_traits_duplicate_function(&fn_copy, estrdup(fn->common.function_name)); - if (zend_hash_quick_update(&ce->function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, fn, sizeof(zend_function), NULL)==FAILURE) { + if (zend_hash_quick_update(&ce->function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, &fn_copy, sizeof(zend_function), (void**)&fn_copy_p)==FAILURE) { zend_error(E_ERROR, "Trait method %s has not been applied, because failure occured during updating class method table", hash_key->arKey); } - _ADD_MAGIC_METHOD(ce, hash_key->arKey, hash_key->nKeyLength, fn); + _ADD_MAGIC_METHOD(ce, hash_key->arKey, hash_key->nKeyLength, fn_copy_p); /* it could be necessary to update child classes as well */ /* zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t)php_runkit_update_children_methods, 5, dce, dce, &dfe, dfunc, dfunc_len); */ + + zend_function_dtor(fn); } else { zend_function_dtor(fn); - /* efree(fn); */ } return ZEND_HASH_APPLY_REMOVE;
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php