ID: 20882
Comment by: thekid at thekid dot de
Reported By: yota at foo dot com
Status: Open
Bug Type: Zend Engine 2 problem
Operating System: Linux debian woody
PHP Version: 5.0.0-dev
New Comment:
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;
}
Previous Comments:
------------------------------------------------------------------------
[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