diff options
| author | Dmitry Stogov <dmitry@php.net> | 2007-11-12 09:11:49 +0000 |
|---|---|---|
| committer | Dmitry Stogov <dmitry@php.net> | 2007-11-12 09:11:49 +0000 |
| commit | 2ea310593911cb75d4d178c1149f22a693d2a85e (patch) | |
| tree | b701fbcefbdcde509a9b5e6535b4382b30db2a7b /Zend | |
| parent | 9ed8465d1b416d48d7d687b49782115c6e44b84a (diff) | |
| download | php-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-x | Zend/tests/bug42937.phpt | 40 | ||||
| -rw-r--r-- | Zend/zend_object_handlers.c | 28 |
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 */ |
