summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2007-11-12 09:11:49 +0000
committerDmitry Stogov <dmitry@php.net>2007-11-12 09:11:49 +0000
commit2ea310593911cb75d4d178c1149f22a693d2a85e (patch)
treeb701fbcefbdcde509a9b5e6535b4382b30db2a7b /Zend
parent9ed8465d1b416d48d7d687b49782115c6e44b84a (diff)
downloadphp-git-2ea310593911cb75d4d178c1149f22a693d2a85e.tar.gz
Fixed bug #42937 (__call() method not invoked when methods are called on parent from child class).
Diffstat (limited to 'Zend')
-rwxr-xr-xZend/tests/bug42937.phpt40
-rw-r--r--Zend/zend_object_handlers.c28
2 files changed, 64 insertions, 4 deletions
diff --git a/Zend/tests/bug42937.phpt b/Zend/tests/bug42937.phpt
new file mode 100755
index 0000000000..875f0d9225
--- /dev/null
+++ b/Zend/tests/bug42937.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Bug #42937 (__call() method not invoked when methods are called on parent from child class)
+--FILE--
+<?php
+class A {
+ function __call($strMethod, $arrArgs) {
+ echo "$strMethod\n";
+ }
+}
+
+class C {
+ function __call($strMethod, $arrArgs) {
+ echo "$strMethod\n";
+ }
+}
+
+class B extends A {
+ function test() {
+ self::test1();
+ parent::test2();
+ A::test3();
+ B::test4();
+ C::test5();
+ }
+}
+
+$a = new A();
+$a->test();
+
+$b = new B();
+$b->test();
+?>
+--EXPECTF--
+test
+test1
+test2
+test3
+test4
+
+Fatal error: Call to undefined method C::test5() in %sbug42937.php on line 20
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 901c28ce68..e6a6e485de 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -831,12 +831,32 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *f
zend_function *fbc;
if (zend_hash_find(&ce->function_table, function_name_strval, function_name_strlen+1, (void **) &fbc)==FAILURE) {
- char *class_name = ce->name;
+ if (ce->__call &&
+ EG(This) &&
+ Z_OBJ_HT_P(EG(This))->get_class_entry &&
+ instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
+ zend_internal_function *call_user_call = emalloc(sizeof(zend_internal_function));
- if (!class_name) {
- class_name = "";
+ call_user_call->type = ZEND_INTERNAL_FUNCTION;
+ call_user_call->module = 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 = ce;
+ call_user_call->fn_flags = 0;
+ call_user_call->function_name = estrndup(function_name_strval, function_name_strlen);
+ call_user_call->pass_rest_by_reference = 0;
+ call_user_call->return_reference = ZEND_RETURN_VALUE;
+
+ return (union _zend_function *)call_user_call;
+ } else {
+ char *class_name = ce->name;
+
+ if (!class_name) {
+ class_name = "";
+ }
+ zend_error(E_ERROR, "Call to undefined method %s::%s()", class_name, function_name_strval);
}
- zend_error(E_ERROR, "Call to undefined method %s::%s()", class_name, function_name_strval);
}
if (fbc->op_array.fn_flags & ZEND_ACC_PUBLIC) {
/* No further checks necessary, most common case */