|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2002-12-07 16:05 UTC] 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.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Dec 27 05:00:01 2025 UTC |
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, MatrixThis 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; }