cvs: ZendEngine2(PHP_5_3) / zend_object_handlers.c php-src NEWS

"Andrei Zmievski" <[email protected]>
Newsgroups gmane.comp.php.cvs.zend
Message-ID <cvsandrei1231366359@cvsserver>
andrei		Wed Jan  7 22:12:39 2009 UTC

  Modified files:              (Branch: PHP_5_3)
    /php-src	NEWS 
    /ZendEngine2	zend_object_handlers.c 
  Log:
  Changed __call() to be invoked on private/protected method access,
  similar to properties and __get().
  
  
http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.965.2.437&r2=1.2027.2.547.2.965.2.438&diff_format=u
Index: php-src/NEWS
diff -u php-src/NEWS:1.2027.2.547.2.965.2.437 php-src/NEWS:1.2027.2.547.2.965.2.438
--- php-src/NEWS:1.2027.2.547.2.965.2.437	Wed Jan  7 16:32:07 2009
+++ php-src/NEWS	Wed Jan  7 22:12:39 2009
@@ -1,6 +1,8 @@
 PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2009, PHP 5.3.0 Alpha 4
+- Changed __call() to be invoked on private/protected method access, similar to
+  properties and __get(). (Andrei)
 - Upgraded bundled sqlite to version 3.6.7. (Scott)
 
 - Deprecated session_register(), session_unregister() and
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_object_handlers.c?r1=1.135.2.6.2.22.2.24&r2=1.135.2.6.2.22.2.25&diff_format=u
Index: ZendEngine2/zend_object_handlers.c
diff -u ZendEngine2/zend_object_handlers.c:1.135.2.6.2.22.2.24 ZendEngine2/zend_object_handlers.c:1.135.2.6.2.22.2.25
--- ZendEngine2/zend_object_handlers.c:1.135.2.6.2.22.2.24	Sat Jan  3 17:48:39 2009
+++ ZendEngine2/zend_object_handlers.c	Wed Jan  7 22:12:39 2009
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_object_handlers.c,v 1.135.2.6.2.22.2.24 2009/01/03 17:48:39 helly Exp $ */
+/* $Id: zend_object_handlers.c,v 1.135.2.6.2.22.2.25 2009/01/07 22:12:39 andrei Exp $ */
 
 #include "zend.h"
 #include "zend_globals.h"
@@ -781,6 +781,24 @@
 }
 /* }}} */
 
+static inline union _zend_function *zend_get_user_call_function(zend_object *zobj, char *method_name, int method_len) /* {{{ */
+{
+	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 = ZEND_ACC_CALL_VIA_HANDLER;
+	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;
+
+	return (union _zend_function *)call_user_call;
+}
+/* }}} */
+
 static union _zend_function *zend_std_get_method(zval **object_ptr, char *method_name, int method_len TSRMLS_DC) /* {{{ */
 {
 	zend_object *zobj;
@@ -797,19 +815,7 @@
 	if (zend_hash_find(&zobj->ce->function_table, lc_method_name, method_len+1, (void **)&fbc) == FAILURE) {
 		free_alloca(lc_method_name, use_heap);
 		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 = ZEND_ACC_CALL_VIA_HANDLER;
-			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;
-
-			return (union _zend_function *)call_user_call;
+			return zend_get_user_call_function(zobj, method_name, method_len);
 		} else {
 			return NULL;
 		}
@@ -820,12 +826,18 @@
 		zend_function *updated_fbc;
 
 		/* Ensure that if we're calling a private function, we're allowed to do so.
+		 * If we're not and __call() handler exists, invoke it, otherwise error out.
 		 */
 		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) {
+				fbc = zend_get_user_call_function(zobj, method_name, method_len);
+			} 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...
@@ -843,9 +855,14 @@
 		}
 		if ((fbc->common.fn_flags & ZEND_ACC_PROTECTED)) {
 			/* Ensure that if we're calling a protected function, we're allowed to do so.
+			 * If we're not and __call() handler exists, invoke it, otherwise error out.
 			 */
 			if (!zend_check_protected(zend_get_function_root_class(fbc), EG(scope))) {
-				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 (zobj->ce->__call) {
+					fbc = zend_get_user_call_function(zobj, method_name, method_len);
+				} 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 : "");
+				}
 			}
 		}
 	}



-- 
Zend Engine CVS Mailing List (http://cvs.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.