ID: 20882 Updated by: [EMAIL PROTECTED] Reported By: yota at foo dot com -Status: Open +Status: Closed Bug Type: Zend Engine 2 problem Operating System: Linux debian woody PHP Version: 5.0.0-dev -Assigned To: +Assigned To: helly New Comment:
This bug has been fixed in CVS. In case this was a PHP problem, snapshots of the sources are packaged every three hours; this change will be in the next snapshot. You can grab the snapshot at http://snaps.php.net/. In case this was a documentation problem, the fix will show up soon at http://www.php.net/manual/. In case this was a PHP.net website problem, the change will show up on the PHP.net site and on the mirror sites in short time. Thank you for the report, and for helping us make PHP better. Previous Comments: ------------------------------------------------------------------------ [2003-04-19 09:22:19] thekid at thekid dot de This can be fixed with this simple patch: Index: Zend/zend_compile.c =================================================================== RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.412 diff -u -r1.412 zend_compile.c --- Zend/zend_compile.c 11 Apr 2003 17:30:41 -0000 1.412 +++ Zend/zend_compile.c 19 Apr 2003 14:20:02 -0000 @@ -1611,27 +1611,13 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) { - zend_function *function; - - if (!ce->parent || ce->constructor) { - return; - } + zend_function *function; - if (!zend_hash_exists(&ce->function_table, ce->name, ce->name_length+1)) { - if (zend_hash_find(&ce->parent->function_table, ce->parent->name, ce->parent->name_length+1, (void **) &function)==SUCCESS) { - /* inherit parent's constructor */ - zend_hash_update(&ce->function_table, ce->name, ce->name_length+1, function, sizeof(zend_function), NULL); - function_add_ref(function); - } - } - if (zend_hash_find(&ce->parent->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME), (void **) &function)==SUCCESS) { - /* inherit parent's constructor */ - zend_hash_update(&ce->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME), function, sizeof(zend_function), NULL); - function_add_ref(function); - } - ce->constructor = ce->parent->constructor; + if (!ce->parent) { + return; + } if (!ce->__get) { - ce->__get = ce->parent->__get; + ce->__get = ce->parent->__get; } if (!ce->__set) { ce->__set = ce->parent->__set; @@ -1639,7 +1625,24 @@ if (!ce->__call) { ce->__call = ce->parent->__call; } - ce->create_object = ce->parent->create_object; + if (ce->constructor) { + return; + } + + if (!zend_hash_exists(&ce->function_table, ce->name, ce->name_length+1)) { + if (zend_hash_find(&ce->parent->function_table, ce->parent->name, ce->parent->name_length+1, (void **) &function)==SUCCESS) { + /* inherit parent's constructor */ + zend_hash_update(&ce->function_table, ce->name, ce->name_length+1, function, sizeof(zend_function), NULL); + function_add_ref(function); + } + } + if (zend_hash_find(&ce->parent->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME), (void **) &function)==SUCCESS) { + /* inherit parent's constructor */ + zend_hash_update(&ce->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME), function, sizeof(zend_function), NULL); + function_add_ref(function); + } + ce->constructor = ce->parent->constructor; + ce->create_object = ce->parent->create_object; } ------------------------------------------------------------------------ [2003-01-29 21:48:27] bjack at tut dot by I have found the same problem, but it fires only if child class has __construct(). Look at this code: error_reporting(E_ALL); class Base { function __construct() { print "Base::Construct()\n"; } function __get($name) { return $this->{"__get$name"}(); } function __set($name, $value) { return $this->{"__set$name"}($value); } } class Child extends Base { function __construct() { parent::__construct(); } function __getFoo() { return 'zoo'; } } $q = new Child(); // where we get an Notice: Undefined property: foo print $q->foo; ----------------------------------- Sample without the problem: error_reporting(E_ALL); class Base { function __construct() { print "Base::Construct()\n"; } function __get($name) { return $this->{"__get$name"}(); } function __set($name, $value) { return $this->{"__set$name"}($value); } } class Child extends Base { function __getFoo() { return 'zoo'; } } $q = new Child(); // prints 'zoo', all is OK print $q->foo; ------------------------------------- Moveover, the Child class inherites __get, __set from Base in both cases above. $q = new Child(); print_r(get_class_methods(get_class($q))); result is Array ( [0] => __construct [1] => __getfoo [2] => __get [3] => __set ) -- BR, Matrix ------------------------------------------------------------------------ [2002-12-07 16:05:31] yota at foo dot com // like everyday error_reporting(E_ALL); class Foo { function __get($var) { // ... some code to retrieve var } }; overload('Foo'); // activate overload $f = new Foo(); echo $f->bar; // issued a NOTICE ERROR (unknown // property) Of course we can't declare a var $bar in Foo as overload (for an obscure reason and unlike any other language) only works if $bar does not exists in Foo. Don't ask me to remove error_reporting line, i won't and i'm sure you know why :) ZendEngine2 has the same problem, __get, __set, __call are just unusable. They need to be activated even if the target property or function exists. Thank for thinking about that, and thousands thanks if you correct it. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=20882&edit=1