--- /dev/null
+--TEST--
+Bug #46246 (difference between call_user_func(array($this, $method)) and $this->$method())
+--FILE--
+<?php
+class A
+{
+ private function Test()
+ {
+ echo 'Hello from '.get_class($this)."\n";
+ }
+
+ public function call($method, $args = array())
+ {
+ $this->Test();
+ $this->$method();
+ call_user_func(array($this, $method));
+ }
+}
+
+class B extends A
+{
+ protected function Test()
+ {
+ echo 'Overridden hello from '.get_class($this)."\n";
+ }
+}
+
+$a = new A;
+$b = new B;
+
+$a->call('Test');
+$b->call('Test');
+?>
+--EXPECT--
+Hello from A
+Hello from A
+Hello from A
+Hello from B
+Hello from B
+Hello from B
lmname = zend_u_str_case_fold(Z_TYPE_P(callable), mname, mlen, 1, &lmlen);
if (zend_u_hash_find(ftable, Z_TYPE_P(callable), lmname, lmlen+1, (void**)&fcc->function_handler) == SUCCESS) {
retval = 1;
- } else if (fcc->object_pp && Z_OBJ_HT_PP(fcc->object_pp)->get_method) {
- zstr method = mname;
- int method_len = mlen;
-
- if (UG(unicode) && Z_TYPE_P(callable) == IS_STRING) {
- zend_string_to_unicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &method.u, &method_len, mname.s, mlen TSRMLS_CC);
- } else if (!UG(unicode) && Z_TYPE_P(callable) == IS_UNICODE) {
- zend_unicode_to_string(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &method.s, &method_len, mname.u, mlen TSRMLS_CC);
- }
- fcc->function_handler = Z_OBJ_HT_PP(fcc->object_pp)->get_method(fcc->object_pp, method, method_len TSRMLS_CC);
- if (method.v != mname.v) {
- efree(method.v);
+ if ((fcc->function_handler->op_array.fn_flags & ZEND_ACC_CHANGED) &&
+ EG(scope) &&
+ instanceof_function(fcc->function_handler->common.scope, EG(scope) TSRMLS_CC)) {
+ zend_function *priv_fbc;
+
+ if (zend_u_hash_find(&EG(scope)->function_table, Z_TYPE_P(callable), lmname, lmlen+1, (void **) &priv_fbc)==SUCCESS
+ && priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE
+ && priv_fbc->common.scope == EG(scope)) {
+ fcc->function_handler = priv_fbc;
+ }
+ }
+ } else if (fcc->object_pp) {
+ if (Z_OBJ_HT_PP(fcc->object_pp)->get_method) {
+ zstr method = mname;
+ int method_len = mlen;
+
+ if (UG(unicode) && Z_TYPE_P(callable) == IS_STRING) {
+ zend_string_to_unicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &method.u, &method_len, mname.s, mlen TSRMLS_CC);
+ } else if (!UG(unicode) && Z_TYPE_P(callable) == IS_UNICODE) {
+ zend_unicode_to_string(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &method.s, &method_len, mname.u, mlen TSRMLS_CC);
+ }
+ fcc->function_handler = Z_OBJ_HT_PP(fcc->object_pp)->get_method(fcc->object_pp, method, method_len TSRMLS_CC);
+ if (method.v != mname.v) {
+ efree(method.v);
+ }
+ retval = fcc->function_handler ? 1 : 0;
+ call_via_handler = 1;
}
- retval = fcc->function_handler ? 1 : 0;
- call_via_handler = 1;
} else if (fcc->calling_scope) {
if (fcc->calling_scope->get_static_method) {
fcc->function_handler = fcc->calling_scope->get_static_method(fcc->calling_scope, Z_TYPE_P(callable), mname, mlen TSRMLS_CC);