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