Edit report at https://bugs.php.net/bug.php?id=38122&edit=1
ID: 38122 Comment by: francescrosasbosque at gmail dot com Reported by: toomuchphp-phpbugs at yahoo dot com Summary: Misleading error message for recursive use of __get() Status: Open Type: Feature/Change Request Package: Feature/Change Request PHP Version: 5.2.0RC1 Block user comment: N Private report: N New Comment: It still occurs in 5.4.7 Also, why triggering a warning? Why not make it behave just like any other function? class Test { function get() { return $this->get(); } } (new Test)->get(); # Output PHP Fatal error: Maximum function nesting level of '100' reached, aborting! in /private/tmp/foo.php on line 5 PHP Stack trace: PHP 1. {main}() /private/tmp/foo.php:0 PHP 2. Test->get() /private/tmp/foo.php:9 PHP 3. Test->get() /private/tmp/foo.php:5 PHP 4. Test->get() /private/tmp/foo.php:5 ... Previous Comments: ------------------------------------------------------------------------ [2006-08-15 02:19:56] toomuchphp-phpbugs at yahoo dot com Apologies for the slightly messed-up examples in previous comments. This is the patch that works for me against 5.2.0RC1. --- zend_object_handlers.c.original Tue Aug 15 11:41:38 2006 +++ zend_object_handlers.c Tue Aug 15 11:45:08 2006 @@ -325,28 +325,36 @@ zend_guard *guard; if (zobj->ce->__get && - zend_get_property_guard(zobj, property_info, member, &guard) == SUCCESS && - !guard->in_get) { - /* have getter - try with it! */ - guard->in_get = 1; /* prevent circular getting */ - rv = zend_std_call_getter(object, member TSRMLS_CC); - guard->in_get = 0; + zend_get_property_guard(zobj, property_info, member, &guard) == SUCCESS) { + /* don't allow recursively calling __get() */ + if(!guard->in_get) { + /* have getter - try with it! */ + guard->in_get = 1; /* prevent circular getting */ + rv = zend_std_call_getter(object, member TSRMLS_CC); + guard->in_get = 0; - if (rv) { - retval = &rv; - if ((type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET) && rv->refcount > 0) { - zval *tmp = rv; + if (rv) { + retval = &rv; + if ((type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET) && rv->refcount > 0) { + zval *tmp = rv; - ALLOC_ZVAL(rv); - *rv = *tmp; - zval_copy_ctor(rv); - rv->is_ref = 0; - rv->refcount = 0; - if (Z_TYPE_P(rv) != IS_OBJECT) { - zend_error(E_NOTICE, "Indirect modification of overloaded property %s::$%s has no effect", zobj->ce->name, Z_STRVAL_P(member)); + ALLOC_ZVAL(rv); + *rv = *tmp; + zval_copy_ctor(rv); + rv->is_ref = 0; + rv->refcount = 0; + if (Z_TYPE_P(rv) != IS_OBJECT) { + zend_error(E_NOTICE, "Indirect modification of overloaded property %s::$%s has no effect", zobj->ce->name, Z_STRVAL_P(member)); + } } + } else { + retval = &EG(uninitialized_zval_ptr); + } + } + else { + if (!silent) { + zend_error(E_WARNING,"Recursive use of __get() trying to read property: %s::$%s", zobj->ce->name, Z_STRVAL_P(member)); } - } else { retval = &EG(uninitialized_zval_ptr); } } else { ------------------------------------------------------------------------ [2006-08-02 05:02:12] toomuchphp-phpbugs at yahoo dot com Also occurs in PHP-5.2.0RC1. ------------------------------------------------------------------------ [2006-07-17 08:14:27] toomuchphp-phpbugs at yahoo dot com Description: ------------ Recursive use of __get() results in the misleading error message "Notice: Undefined property: someClass::$foo in file.php". It appears at first as though __get() is not being called for some properties and there is no apparent reason why, when the problem is really accidental recursion. PHP correctly detects the recursion and aborts __get(), but the error gives no indication of the recursion problem and it can be very difficult to figure out why __get() is not being called. I can provide a fix for zend_object_handlers.c, but it really is just a 60-second change to capture the recursiveness error and output an alternative error message. Reproduce code: --------------- class test { function __get($var) { return $this->$var; } } $obj = new test; echo $obj->foo; Expected result: ---------------- Warning: Recursive use of __get() while accessing test::$foo; cannot read property recursive::$foo in <file> on line x Actual result: -------------- Notice: Undefined property: test::$foo in <file> on line x ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=38122&edit=1