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

Reply via email to