A colleague at Digg pointed me to this blog entry: http://atomized.org/2008/11/more-tough-love-from-php/
To me it looks like a large inconsistency in the way we invoke overloaded handlers for members vs. methods. I am not sure how it came to be this way, but it's probably something we should fix. We can either remove the call to __get() on private member access, or add call to __call() on private method invocation. The former approach presents more of a BC problem IMHO, so I am advocating the latter. I've attached a simple patch for consideration. -Andrei
Index: Zend/zend_object_handlers.c =================================================================== RCS file: /repository/ZendEngine2/zend_object_handlers.c,v retrieving revision 1.135.2.6.2.30 diff -u -r1.135.2.6.2.30 zend_object_handlers.c --- Zend/zend_object_handlers.c 31 Dec 2008 11:17:33 -0000 1.135.2.6.2.30 +++ Zend/zend_object_handlers.c 6 Jan 2009 22:07:38 -0000 @@ -799,10 +799,27 @@ /* Ensure that if we're calling a private function, we're allowed to do so. */ updated_fbc = zend_check_private_int(fbc, Z_OBJ_HANDLER_P(object, get_class_entry)(object TSRMLS_CC), lc_method_name, method_len TSRMLS_CC); - if (!updated_fbc) { - zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : ""); + if (updated_fbc) { + fbc = updated_fbc; + } else { + if (zobj->ce->__call) { + zend_internal_function *call_user_call = emalloc(sizeof(zend_internal_function)); + call_user_call->type = ZEND_INTERNAL_FUNCTION; + call_user_call->module = zobj->ce->module; + call_user_call->handler = zend_std_call_user_call; + call_user_call->arg_info = NULL; + call_user_call->num_args = 0; + call_user_call->scope = zobj->ce; + call_user_call->fn_flags = 0; + call_user_call->function_name = estrndup(method_name, method_len); + call_user_call->pass_rest_by_reference = 0; + call_user_call->return_reference = ZEND_RETURN_VALUE; + + fbc = (zend_function *)call_user_call; + } else { + zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : ""); + } } - fbc = updated_fbc; } else { /* Ensure that we haven't overridden a private function and end up calling * the overriding public function...
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php