--EXPECTF--
===A===
TestB::doSomething(1)
-
-Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method TestA::doSomething() should not be called statically, assuming $this from compatible context TestB in %s on line %d
TestA::doSomething(2)
int(1)
===C===
TestB::doSomethingParent(1)
-
-Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method TestA::doSomethingParent() should not be called statically, assuming $this from compatible context TestB in %s on line %d
TestA::doSomethingParent(2)
int(1)
Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method foo::test() should not be called statically in %s on line %d
-Strict Standards: Non-static method foo::test() should not be called statically in %s on line %d
-
Strict Standards: Non-static method bar::show() should not be called statically in %s on line %d
object(foo)#%d (0) {
}
} else {
fcc->called_scope = EG(called_scope);
fcc->calling_scope = EG(scope);
+ if (!fcc->object_pp) {
+ fcc->object_pp = EG(This) ? &EG(This) : NULL;
+ }
ret = 1;
}
} else if (lcname_len == sizeof("parent") - 1 &&
} else {
fcc->called_scope = EG(called_scope);
fcc->calling_scope = EG(scope)->parent;
+ if (!fcc->object_pp) {
+ fcc->object_pp = EG(This) ? &EG(This) : NULL;
+ }
ret = 1;
}
} else if (lcname_len == sizeof("static") - 1 &&
} else {
fcc->called_scope = EG(called_scope);
fcc->calling_scope = EG(called_scope);
+ if (!fcc->object_pp) {
+ fcc->object_pp = EG(This) ? &EG(This) : NULL;
+ }
ret = 1;
}
} else if (zend_u_lookup_class(utype, name, name_len, &pce TSRMLS_CC) == SUCCESS) {
- fcc->called_scope = fcc->calling_scope = *pce;
+ zend_class_entry *scope = EG(active_op_array) ? EG(active_op_array)->scope : NULL;
+
+ fcc->calling_scope = *pce;
+ if (scope && !fcc->object_pp && EG(This) &&
+ instanceof_function(Z_OBJCE_P(EG(This)), scope TSRMLS_CC) &&
+ instanceof_function(scope, fcc->calling_scope TSRMLS_CC)) {
+ fcc->object_pp = &EG(This);
+ fcc->called_scope = Z_OBJCE_PP(fcc->object_pp);
+ } else {
+ fcc->called_scope = fcc->object_pp ? Z_OBJCE_PP(fcc->object_pp) : fcc->calling_scope;
+ }
ret = 1;
} else {
if (error) {
static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fcall_info_cache *fcc, char **error TSRMLS_DC) /* {{{ */
{
zend_class_entry *ce_org = fcc->calling_scope;
- int retval;
+ int retval = 0;
zstr lmname, mname, colon = NULL_ZSTR;
- unsigned int clen = 0, mlen;
+ unsigned int clen = 0, lmlen, mlen;
zend_class_entry *last_scope;
HashTable *ftable;
int call_via_handler = 0;
Z_USTRVAL_P(callable)[0] == ':' &&
Z_USTRVAL_P(callable)[1] == ':'
) {
- zstr tmp;
-
- tmp.u = Z_USTRVAL_P(callable) + 2;
- lmname = zend_u_str_case_fold(IS_UNICODE, tmp, Z_USTRLEN_P(callable)-2, 1, &mlen);
+ mlen = Z_USTRLEN_P(callable) - 2;
+ mname.u = Z_USTRVAL_P(callable) + 2;
+ lmname = zend_u_str_case_fold(IS_UNICODE, mname, mlen, 1, &lmlen);
} else if (Z_TYPE_P(callable) == IS_STRING &&
Z_STRVAL_P(callable)[0] == ':' &&
Z_STRVAL_P(callable)[1] == ':'
) {
- zstr tmp;
-
- tmp.s = Z_STRVAL_P(callable) + 2;
- lmname = zend_u_str_case_fold(IS_STRING, tmp, Z_STRLEN_P(callable)-2, 1, &mlen);
+ mlen = Z_USTRLEN_P(callable) - 2;
+ mname.u = Z_USTRVAL_P(callable) + 2;
+ lmname = zend_u_str_case_fold(IS_STRING, mname, mlen, 1, &lmlen);
} else {
- lmname = zend_u_str_case_fold(Z_TYPE_P(callable), Z_UNIVAL_P(callable), Z_UNILEN_P(callable), 1, &mlen);
+ mlen = Z_UNILEN_P(callable);
+ mname = Z_UNIVAL_P(callable);
+ lmname = zend_u_str_case_fold(Z_TYPE_P(callable), Z_UNIVAL_P(callable), Z_UNILEN_P(callable), 1, &lmlen);
}
/* Check if function with given name exists.
* This may be a compound name that includes namespace name */
- if (zend_u_hash_find(EG(function_table), Z_TYPE_P(callable), lmname, mlen+1, (void**)&fcc->function_handler) == SUCCESS) {
+ if (zend_u_hash_find(EG(function_table), Z_TYPE_P(callable), lmname, lmlen+1, (void**)&fcc->function_handler) == SUCCESS) {
efree(lmname.v);
return 1;
}
if (error) zend_spprintf(error, 0, "class '%v' is not a subclass of '%v'", ce_org->name, fcc->calling_scope->name);
return 0;
}
- lmname = zend_u_str_case_fold(Z_TYPE_P(callable), mname, mlen, 1, &mlen);
} else if (ce_org) {
/* Try to fetch find static method of given class. */
- lmname = zend_u_str_case_fold(Z_TYPE_P(callable), Z_UNIVAL_P(callable), Z_UNILEN_P(callable), 1, &mlen);
+ mlen = Z_UNILEN_P(callable);
+ mname = Z_UNIVAL_P(callable);
ftable = &ce_org->function_table;
fcc->calling_scope = ce_org;
} else {
/* We already checked for plain function before. */
- if (error) zend_spprintf(error, 0, "function '%Z' not found or invalid function name", callable);
+ if (error && !(check_flags & IS_CALLABLE_CHECK_SILENT)) {
+ zend_spprintf(error, 0, "function '%Z' not found or invalid function name", callable);
+ }
return 0;
}
- retval = zend_u_hash_find(ftable, Z_TYPE_P(callable), lmname, mlen+1, (void**)&fcc->function_handler) == SUCCESS ? 1 : 0;
-
- if (!retval) {
- if (fcc->object_pp && fcc->calling_scope && fcc->calling_scope->__call != 0) {
- retval = 1;
- call_via_handler = 1;
- fcc->function_handler = fcc->calling_scope->__call;
+ 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);
+ }
+ 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);
} else {
- if (!fcc->object_pp && fcc->calling_scope && (fcc->calling_scope->__callstatic || fcc->calling_scope->__call)) {
- if (fcc->calling_scope->__call &&
- EG(This) &&
- Z_OBJ_HT_P(EG(This))->get_class_entry &&
- instanceof_function(Z_OBJCE_P(EG(This)), fcc->calling_scope TSRMLS_CC)) {
- retval = 1;
- call_via_handler = 1;
- fcc->function_handler = fcc->calling_scope->__call;
- fcc->object_pp = &EG(This);
- } else if (fcc->calling_scope->__callstatic) {
- retval = 1;
- call_via_handler = 1;
- fcc->function_handler = fcc->calling_scope->__callstatic;
- }
- }
-
- if (retval == 0) {
- if (fcc->calling_scope) {
- if (error) zend_spprintf(error, 0, "class '%v' does not have a method '%v'", fcc->calling_scope->name, lmname);
- } else {
- if (error) zend_spprintf(error, 0, "function '%v' does not exist", lmname);
- }
- }
+ fcc->function_handler = zend_std_get_static_method(fcc->calling_scope, Z_TYPE_P(callable), mname, mlen TSRMLS_CC);
}
- } else {
- if (fcc->calling_scope) {
- if (!fcc->object_pp && !(fcc->function_handler->common.fn_flags & ZEND_ACC_STATIC)) {
+ retval = fcc->function_handler ? 1 : 0;
+ call_via_handler = 1;
+ }
+ efree(lmname.v);
+
+ if (retval) {
+ if (fcc->calling_scope && !call_via_handler) {
+ if (!fcc->object_pp && !(fcc->function_handler->common.fn_flags & ZEND_ACC_STATIC)) {
int severity;
char *verb;
if (fcc->function_handler->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
}
if (retval && (check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0) {
if (fcc->function_handler->op_array.fn_flags & ZEND_ACC_PRIVATE) {
- if (!zend_check_private(fcc->function_handler, fcc->object_pp ? Z_OBJCE_PP(fcc->object_pp) : EG(scope), lmname, mlen TSRMLS_CC)) {
+ if (!zend_check_private(fcc->function_handler, fcc->object_pp ? Z_OBJCE_PP(fcc->object_pp) : EG(scope), mname, mlen TSRMLS_CC)) {
if (error) {
if (*error) {
efree(*error);
}
}
}
+ } else if (error && !(check_flags & IS_CALLABLE_CHECK_SILENT)) {
+ if (fcc->calling_scope) {
+ if (error) zend_spprintf(error, 0, "class '%v' does not have a method '%R'", fcc->calling_scope->name, Z_TYPE_P(callable), mname);
+ } else {
+ if (error) zend_spprintf(error, 0, "function '%R' does not exist", Z_TYPE_P(callable), mname);
+ }
}
if (fcc->object_pp) {
fcc->called_scope = Z_OBJCE_PP(fcc->object_pp);
}
- efree(lmname.v);
- if (retval && !call_via_handler) {
+ if (retval) {
fcc->initialized = 1;
}
return retval;
}
/* }}} */
-ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, zval *callable_name, zend_fcall_info_cache *fcc, char **error TSRMLS_DC) /* {{{ */
+ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval **object_pp, uint check_flags, zval *callable_name, zend_fcall_info_cache *fcc, char **error TSRMLS_DC) /* {{{ */
{
+ zend_bool ret;
zend_fcall_info_cache fcc_local;
if (callable_name) {
switch (Z_TYPE_P(callable)) {
case IS_STRING:
case IS_UNICODE:
- if (callable_name) {
+ if (object_pp && *object_pp) {
+ fcc->object_pp = object_pp;
+ fcc->calling_scope = Z_OBJCE_PP(object_pp);
+ if (callable_name) {
+ if (UG(unicode)) {
+ Z_TYPE_P(callable_name) = IS_UNICODE;
+ Z_USTRLEN_P(callable_name) = fcc->calling_scope->name_length + Z_UNILEN_P(callable) + 2;
+ Z_USTRVAL_P(callable_name) = eumalloc(Z_USTRLEN_P(callable_name)+1);
+ memcpy(Z_USTRVAL_P(callable_name), fcc->calling_scope->name.u, UBYTES(fcc->calling_scope->name_length));
+ Z_USTRVAL_P(callable_name)[fcc->calling_scope->name_length] = ':';
+ Z_USTRVAL_P(callable_name)[fcc->calling_scope->name_length+1] = ':';
+ if (Z_TYPE_P(callable) == IS_UNICODE) {
+ u_memcpy(Z_USTRVAL_P(callable_name)+fcc->calling_scope->name_length+2, Z_USTRVAL_P(callable), Z_USTRLEN_P(callable)+1);
+ } else {
+ zval *method = callable;
+ zval copy;
+ int use_copy;
+
+ zend_make_unicode_zval(method, ©, &use_copy);
+ u_memcpy(Z_USTRVAL_P(callable_name)+fcc->calling_scope->name_length+2, Z_USTRVAL(copy), Z_USTRLEN(copy)+1);
+ zval_dtor(©);
+ }
+ } else {
+ Z_TYPE_P(callable_name) = IS_STRING;
+ Z_STRLEN_P(callable_name) = fcc->calling_scope->name_length + Z_UNILEN_P(callable) + 2;
+ Z_STRVAL_P(callable_name) = emalloc(Z_STRLEN_P(callable_name)+1);
+ memcpy(Z_STRVAL_P(callable_name), fcc->calling_scope->name.s, fcc->calling_scope->name_length);
+ Z_STRVAL_P(callable_name)[fcc->calling_scope->name_length] = ':';
+ Z_STRVAL_P(callable_name)[fcc->calling_scope->name_length+1] = ':';
+ if (Z_TYPE_P(callable) == IS_STRING) {
+ memcpy(Z_STRVAL_P(callable_name)+fcc->calling_scope->name_length+2, Z_STRVAL_P(callable), Z_STRLEN_P(callable)+1);
+ } else {
+ zval *method = callable;
+ zval copy;
+ int use_copy;
+
+ zend_make_string_zval(method, ©, &use_copy);
+ memcpy(Z_STRVAL_P(callable_name)+fcc->calling_scope->name_length+2, Z_STRVAL(copy), Z_STRLEN(copy)+1);
+ zval_dtor(©);
+ }
+ }
+ }
+ } else if (callable_name) {
*callable_name = *callable;
zval_copy_ctor(callable_name);
convert_to_text(callable_name);
}
if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
+ fcc->called_scope = fcc->calling_scope;
return 1;
}
- return zend_is_callable_check_func(check_flags, callable, fcc, error TSRMLS_CC);
+ ret = zend_is_callable_check_func(check_flags, callable, fcc, error TSRMLS_CC);
+ if (fcc == &fcc_local &&
+ fcc->function_handler &&
+ ((fcc->function_handler->type == ZEND_INTERNAL_FUNCTION &&
+ (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER)) ||
+ fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
+ fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
+ if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
+ efree(fcc->function_handler->common.function_name.v);
+ }
+ efree(fcc->function_handler);
+ }
+ return ret;
case IS_ARRAY:
{
}
}
- return zend_is_callable_check_func(check_flags, *method, fcc, error TSRMLS_CC);
+ ret = zend_is_callable_check_func(check_flags, *method, fcc, error TSRMLS_CC);
+ if (fcc == &fcc_local &&
+ fcc->function_handler &&
+ ((fcc->function_handler->type == ZEND_INTERNAL_FUNCTION &&
+ (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER)) ||
+ fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
+ fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
+ if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION) {
+ efree(fcc->function_handler->common.function_name.v);
+ }
+ efree(fcc->function_handler);
+ }
+ return ret;
+
} else {
if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
if (!obj || (Z_TYPE_PP(obj) != IS_OBJECT && Z_TYPE_PP(obj) != IS_STRING && Z_TYPE_PP(obj) != IS_UNICODE)) {
{
TSRMLS_FETCH();
- return zend_is_callable_ex(callable, check_flags, callable_name, NULL, NULL TSRMLS_CC);
+ return zend_is_callable_ex(callable, NULL, check_flags, callable_name, NULL, NULL TSRMLS_CC);
}
/* }}} */
{
zend_fcall_info_cache fcc;
- if (zend_is_callable_ex(callable, IS_CALLABLE_STRICT, callable_name, &fcc, NULL TSRMLS_CC)) {
+ if (zend_is_callable_ex(callable, NULL, IS_CALLABLE_STRICT, callable_name, &fcc, NULL TSRMLS_CC)) {
if ((Z_TYPE_P(callable) == IS_STRING ||
Z_TYPE_P(callable) == IS_UNICODE) &&
fcc.calling_scope) {
add_next_index_text(callable, fcc.calling_scope->name, 1);
add_next_index_text(callable, fcc.function_handler->common.function_name, 1);
}
+ if (fcc.function_handler &&
+ ((fcc.function_handler->type == ZEND_INTERNAL_FUNCTION &&
+ (fcc.function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER)) ||
+ fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
+ fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
+ if (fcc.function_handler->type != ZEND_OVERLOADED_FUNCTION) {
+ efree(fcc.function_handler->common.function_name.v);
+ }
+ efree(fcc.function_handler);
+ }
return 1;
}
return 0;
ZEND_API int zend_fcall_info_init(zval *callable, uint check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval *callable_name, char **error TSRMLS_DC) /* {{{ */
{
- if (!zend_is_callable_ex(callable, check_flags, callable_name, fcc, error TSRMLS_CC)) {
+ if (!zend_is_callable_ex(callable, NULL, check_flags, callable_name, fcc, error TSRMLS_CC)) {
return FAILURE;
}
#define IS_CALLABLE_CHECK_SYNTAX_ONLY (1<<0)
#define IS_CALLABLE_CHECK_NO_ACCESS (1<<1)
#define IS_CALLABLE_CHECK_IS_STATIC (1<<2)
+#define IS_CALLABLE_CHECK_SILENT (1<<3)
#define IS_CALLABLE_STRICT (IS_CALLABLE_CHECK_IS_STATIC)
-ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, zval *callable_name, zend_fcall_info_cache *fcc, char **error TSRMLS_DC);
+ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval **object_pp, uint check_flags, zval *callable_name, zend_fcall_info_cache *fcc, char **error TSRMLS_DC);
ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, zval *callable_name);
ZEND_API zend_bool zend_make_callable(zval *callable, zval *callable_name TSRMLS_DC);
ZEND_API const char *zend_get_module_version(const char *module_name);
zend_object std;
zend_function func;
zval *this_ptr;
- zend_function *invoke;
} zend_closure;
static zend_class_entry *zend_ce_closure;
ZEND_METHOD(Closure, __invoke) /* {{{ */
{
+ zend_function *func = EG(current_execute_data)->function_state.function;
zval ***arguments;
zval *closure_result_ptr = NULL;
if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == FAILURE) {
efree(arguments);
zend_error(E_ERROR, "Cannot get arguments for calling closure");
- RETURN_FALSE;
- }
-
- if (call_user_function_ex(CG(function_table), NULL, this_ptr, &closure_result_ptr, ZEND_NUM_ARGS(), arguments, 1, NULL TSRMLS_CC) == FAILURE) {
- efree(arguments);
- RETURN_FALSE;
- }
-
- efree(arguments);
- if (closure_result_ptr) {
+ RETVAL_FALSE;
+ } else if (call_user_function_ex(CG(function_table), NULL, this_ptr, &closure_result_ptr, ZEND_NUM_ARGS(), arguments, 1, NULL TSRMLS_CC) == FAILURE) {
+ RETVAL_FALSE;
+ } else if (closure_result_ptr) {
if (Z_ISREF_P(closure_result_ptr) && return_value_ptr) {
if (return_value) {
zval_ptr_dtor(&return_value);
RETVAL_ZVAL(closure_result_ptr, 1, 1);
}
}
-}
-/* }}} */
+ efree(arguments);
-const static zend_function_entry closure_functions[] = { /* {{{ */
- ZEND_ME(Closure, __invoke, NULL, 0)
- {NULL, NULL, NULL}
-};
+ /* destruct the function also, then - we have allocated it in get_method */
+ efree(func->internal_function.function_name.v);
+ efree(func);
+}
/* }}} */
static zend_function *zend_closure_get_constructor(zval *object TSRMLS_DC) /* {{{ */
(ZEND_U_EQUAL(type, lc_name, lc_name_len, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1))
) {
zend_closure *closure = (zend_closure *)zend_object_store_get_object(*object_ptr TSRMLS_CC);
-
- if (!closure->invoke) {
- closure->invoke = (zend_function*)emalloc(sizeof(zend_function));
- closure->invoke->common = closure->func.common;
- closure->invoke->type = ZEND_INTERNAL_FUNCTION;
- closure->invoke->internal_function.handler = ZEND_MN(Closure___invoke);
- closure->invoke->internal_function.module = 0;
- closure->invoke->internal_function.scope = zend_ce_closure;
- if (UG(unicode)) {
- closure->invoke->internal_function.function_name.u = USTR_MAKE(ZEND_INVOKE_FUNC_NAME);
- } else {
- closure->invoke->internal_function.function_name.s = ZEND_INVOKE_FUNC_NAME;
- }
+ zend_function *invoke = (zend_function*)emalloc(sizeof(zend_function));
+
+ invoke->common = closure->func.common;
+ invoke->type = ZEND_INTERNAL_FUNCTION;
+ invoke->internal_function.fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
+ invoke->internal_function.handler = ZEND_MN(Closure___invoke);
+ invoke->internal_function.module = 0;
+ invoke->internal_function.scope = zend_ce_closure;
+ if (UG(unicode)) {
+ invoke->internal_function.function_name.u = USTR_MAKE(ZEND_INVOKE_FUNC_NAME);
+ } else {
+ invoke->internal_function.function_name.s = estrndup(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1);
}
efree(lc_name.v);
- return (zend_function *)closure->invoke;
+ return invoke;
}
efree(lc_name.v);
return NULL;
zval_ptr_dtor(&closure->this_ptr);
}
- if (closure->invoke) {
- if (UG(unicode)) {
- efree(closure->invoke->internal_function.function_name.u);
- }
- efree(closure->invoke);
- }
-
efree(closure);
}
/* }}} */
{
zend_class_entry ce;
- INIT_CLASS_ENTRY(ce, "Closure", closure_functions);
+ INIT_CLASS_ENTRY(ce, "Closure", NULL);
zend_ce_closure = zend_register_internal_class(&ce TSRMLS_CC);
zend_ce_closure->ce_flags |= ZEND_ACC_FINAL_CLASS;
zend_ce_closure->create_object = zend_closure_new;
char *zend_visibility_string(zend_uint fn_flags);
+/* function flag for internal user call handlers __call, __callstatic */
+#define ZEND_ACC_CALL_VIA_HANDLER 0x200000
typedef struct _zend_property_info {
zend_uint flags;
zend_class_entry *current_called_scope;
zend_class_entry *calling_scope = NULL;
zend_class_entry *called_scope = NULL;
- zend_class_entry *check_scope_or_static = NULL;
zval *current_this;
zend_execute_data execute_data;
- zval *method_name;
- zval *params_array;
- int call_via_handler = 0;
char *old_func_name = NULL;
- unsigned int clen, lcname_len;
- int fname_len;
- zstr colon, fname, cname, lcname;
*fci->retval_ptr_ptr = NULL;
}
if (!fci_cache || !fci_cache->initialized) {
- if (Z_TYPE_P(fci->function_name) == IS_ARRAY) { /* assume array($obj, $name) couple */
- zval **tmp_object_ptr, **tmp_real_function_name;
-
- if (zend_hash_index_find(Z_ARRVAL_P(fci->function_name), 0, (void **) &tmp_object_ptr) == FAILURE) {
- return FAILURE;
- }
- if (zend_hash_index_find(Z_ARRVAL_P(fci->function_name), 1, (void **) &tmp_real_function_name) == FAILURE) {
- return FAILURE;
- }
- fci->function_name = *tmp_real_function_name;
- SEPARATE_ZVAL_IF_NOT_REF(tmp_object_ptr);
- fci->object_pp = tmp_object_ptr;
- Z_SET_ISREF_PP(fci->object_pp);
- }
-
- if (fci->object_pp && !*fci->object_pp) {
- fci->object_pp = NULL;
- }
-
- if (fci->object_pp) {
- if (Z_TYPE_PP(fci->object_pp) == IS_OBJECT
- && (!EG(objects_store).object_buckets || !EG(objects_store).object_buckets[Z_OBJ_HANDLE_PP(fci->object_pp)].valid)) {
- return FAILURE;
- }
- /* TBI!! new object handlers */
- if (Z_TYPE_PP(fci->object_pp) == IS_OBJECT) {
- if (!IS_ZEND_STD_OBJECT(**fci->object_pp)) {
- zend_error(E_WARNING, "Cannot use call_user_function on objects without a class entry");
- return FAILURE;
- }
-
- calling_scope = called_scope = Z_OBJCE_PP(fci->object_pp);
- fci->function_table = &calling_scope->function_table;
- EX(object) = *fci->object_pp;
- } else if (Z_TYPE_PP(fci->object_pp) == IS_STRING ||
- Z_TYPE_PP(fci->object_pp) == IS_UNICODE
- ) {
- zend_class_entry **ce;
- int found = FAILURE;
-
- if (Z_UNILEN_PP(fci->object_pp) == sizeof("self") - 1 &&
- ZEND_U_EQUAL(Z_TYPE_PP(fci->object_pp), Z_UNIVAL_PP(fci->object_pp), Z_UNILEN_PP(fci->object_pp), "self", sizeof("self") - 1)
- ) {
- if (!EG(active_op_array) || !EG(active_op_array)->scope) {
- zend_error(E_ERROR, "Cannot access self:: when no class scope is active");
- }
- ce = &(EG(active_op_array)->scope);
- found = (*ce != NULL?SUCCESS:FAILURE);
- fci->object_pp = EG(This)?&EG(This):NULL;
- EX(object) = EG(This);
- calling_scope = *ce;
- called_scope = EG(called_scope) ? EG(called_scope) : calling_scope;
- } else if (EG(active_op_array) &&
- Z_UNILEN_PP(fci->object_pp) == sizeof("parent") - 1 &&
- ZEND_U_EQUAL(Z_TYPE_PP(fci->object_pp), Z_UNIVAL_PP(fci->object_pp), Z_UNILEN_PP(fci->object_pp), "parent", sizeof("parent") - 1)
- ) {
- if (!EG(active_op_array) || !EG(active_op_array)->scope) {
- zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");
- }
- if (!EG(active_op_array)->scope->parent) {
- zend_error(E_ERROR, "Cannot access parent:: when current class scope has no parent");
- }
- ce = &(EG(active_op_array)->scope->parent);
- found = (*ce != NULL?SUCCESS:FAILURE);
- fci->object_pp = EG(This)?&EG(This):NULL;
- EX(object) = EG(This);
- calling_scope = *ce;
- called_scope = EG(called_scope) ? EG(called_scope) : calling_scope;
- } else if (Z_UNILEN_PP(fci->object_pp) == sizeof("static") - 1 &&
- ZEND_U_EQUAL(Z_TYPE_PP(fci->object_pp), Z_UNIVAL_PP(fci->object_pp), Z_UNILEN_PP(fci->object_pp), "static", sizeof("static") - 1)
- ) {
- if (!EG(called_scope)) {
- zend_error(E_ERROR, "Cannot access static:: when no class scope is active");
- }
- ce = &(EG(called_scope));
- found = (EG(called_scope) != NULL?SUCCESS:FAILURE);
- fci->object_pp = EG(This)?&EG(This):NULL;
- EX(object) = EG(This);
- calling_scope = called_scope = EG(called_scope);
- } else {
- zend_class_entry *scope;
- scope = EG(active_op_array) ? EG(active_op_array)->scope : NULL;
-
- found = zend_u_lookup_class(Z_TYPE_PP(fci->object_pp), Z_UNIVAL_PP(fci->object_pp), Z_UNILEN_PP(fci->object_pp), &ce TSRMLS_CC);
- if (found == FAILURE) {
- zend_error(E_ERROR, "Class '%R' not found", Z_TYPE_PP(fci->object_pp), Z_UNIVAL_PP(fci->object_pp));
- }
- if (scope && EG(This) &&
- instanceof_function(Z_OBJCE_P(EG(This)), scope TSRMLS_CC) &&
- instanceof_function(scope, *ce TSRMLS_CC)) {
- fci->object_pp = &EG(This);
- EX(object) = EG(This);
- } else {
- fci->object_pp = NULL;
- }
- calling_scope = called_scope = *ce;
- }
- if (found == FAILURE)
- return FAILURE;
-
- fci->function_table = &(*ce)->function_table;
- } else {
- zend_error(E_NOTICE, "Non-callable array passed to zend_call_function()");
- return FAILURE;
- }
-
- if (fci->function_table == NULL) {
- return FAILURE;
- }
- }
-
- if (Z_TYPE_P(fci->function_name) == IS_OBJECT) {
- if (zend_get_closure(fci->function_name, &calling_scope, &EX(function_state).function, NULL, &fci->object_pp TSRMLS_CC) == SUCCESS) {
- called_scope = calling_scope;
- goto init_fci_cache;
- }
- } else if (Z_TYPE_P(fci->function_name) != IS_STRING &&
- Z_TYPE_P(fci->function_name) != IS_UNICODE
- ) {
- return FAILURE;
- }
-
- if (UG(unicode) && Z_TYPE_P(fci->function_name) == IS_STRING) {
- old_func_name = Z_STRVAL_P(fci->function_name);
-
- Z_STRVAL_P(fci->function_name) = estrndup(Z_STRVAL_P(fci->function_name), Z_STRLEN_P(fci->function_name));
- convert_to_unicode(fci->function_name);
- }
-
- fname = Z_UNIVAL_P(fci->function_name);
- fname_len = Z_UNILEN_P(fci->function_name);
- if (Z_TYPE_P(fci->function_name) == IS_UNICODE) {
- if (fname.u[0] == ':' && fname.u[0] == ':') {
- fname.u += 2;
- fname_len -= 2;
- }
- } else {
- if (fname.s[0] == ':' && fname.s[0] == ':') {
- fname.s += 2;
- fname_len -= 2;
- }
- }
- EX(function_state).function = NULL;
- lcname = zend_u_str_case_fold(Z_TYPE_P(fci->function_name), fname, fname_len, 1, &lcname_len);
-
- if (!fci->object_pp &&
- zend_u_hash_find(fci->function_table, Z_TYPE_P(fci->function_name), lcname, lcname_len + 1, (void **) &EX(function_state).function) == SUCCESS
- ) {
- efree(lcname.v);
- } else {
- efree(lcname.v);
-
- cname = fname;
-
- if (Z_TYPE_P(fci->function_name) == IS_UNICODE) {
- if ((colon.u = u_memrchr(fname.u, ':', fname_len)) != NULL &&
- colon.u > fname.u &&
- *(colon.u - 1) == ':'
- ) {
- clen = colon.u - fname.u - 1;
- fname_len -= (clen + 2);
- fname.u = colon.u + 1;
- } else {
- colon.u = NULL;
- }
- } else {
- if ((colon.s = zend_memrchr(fname.s, ':', fname_len)) != NULL &&
- colon.s > fname.s &&
- *(colon.s - 1) == ':'
- ) {
- clen = colon.s - fname.s - 1;
- fname_len -= (clen + 2);
- fname.s = colon.s + 1;
- } else {
- colon.s = NULL;
- }
- }
- if (colon.v != NULL) {
- zend_class_entry **pce, *ce_child = NULL;
-
- lcname = zend_u_str_case_fold(Z_TYPE_P(fci->function_name), cname, clen, 1, &clen);
- /* caution: lcname is not '\0' terminated */
- if (clen == sizeof("self") - 1 &&
- ZEND_U_EQUAL(Z_TYPE_P(fci->function_name), lcname, clen, "self", sizeof("self") - 1)
- ) {
- if (!EG(active_op_array) || !EG(active_op_array)->scope) {
- zend_error(E_ERROR, "Cannot access self:: when no class scope is active");
- }
- ce_child = EG(active_op_array) ? EG(active_op_array)->scope : NULL;
- called_scope = EG(called_scope) ? EG(called_scope) : ce_child;
- } else if (clen == sizeof("parent") - 1 &&
- ZEND_U_EQUAL(Z_TYPE_P(fci->function_name), lcname, clen, "parent", sizeof("parent") - 1)
- ) {
- if (!EG(active_op_array) || !EG(active_op_array)->scope) {
- zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");
- }
- if (!EG(active_op_array)->scope->parent) {
- zend_error(E_ERROR, "Cannot access parent:: when current class scope has no parent");
- }
- ce_child = EG(active_op_array) && EG(active_op_array)->scope ? EG(active_op_array)->scope->parent : NULL;
- called_scope = EG(called_scope) ? EG(called_scope) : ce_child;
- } else if (clen == sizeof("static") - 1 &&
- ZEND_U_EQUAL(Z_TYPE_P(fci->function_name), lcname, clen, "static", sizeof("static") - 1)
- ) {
- if (!EG(called_scope)) {
- zend_error(E_ERROR, "Cannot access static:: when no class scope is active");
- }
- called_scope = ce_child = EG(called_scope);
- } else if (zend_u_lookup_class_ex(Z_TYPE_P(fci->function_name), lcname, clen, cname, 0, &pce TSRMLS_CC) == SUCCESS) {
- called_scope = ce_child = *pce;
- }
- efree(lcname.v);
-
- if (!ce_child) {
- zend_error(E_ERROR, "Cannot call method %R() or method does not exist", Z_TYPE_P(fci->function_name), Z_UNIVAL_P(fci->function_name));
- return FAILURE;
- }
- check_scope_or_static = calling_scope;
- fci->function_table = &ce_child->function_table;
- calling_scope = ce_child;
- }
-
- if (fci->object_pp) {
- if (Z_OBJ_HT_PP(fci->object_pp)->get_method == NULL) {
- zend_error(E_ERROR, "Object does not support method calls");
- }
- EX(function_state).function =
- Z_OBJ_HT_PP(fci->object_pp)->get_method(fci->object_pp, fname, fname_len TSRMLS_CC);
- if (EX(function_state).function && calling_scope != EX(function_state).function->common.scope) {
- zstr function_name_lc = zend_u_str_tolower_dup(Z_TYPE_P(fci->function_name), fname, fname_len);
- if (zend_u_hash_find(&calling_scope->function_table, Z_TYPE_P(fci->function_name), function_name_lc, fname_len + 1, (void **) &EX(function_state).function) == FAILURE) {
- efree(function_name_lc.v);
- zend_error(E_ERROR, "Cannot call method %v::%R() or method does not exist", calling_scope->name, Z_TYPE_P(fci->function_name), fname);
- }
- efree(function_name_lc.v);
- }
- } else if (calling_scope) {
- if (calling_scope->get_static_method) {
- EX(function_state).function = calling_scope->get_static_method(calling_scope, Z_TYPE_P(fci->function_name), fname, fname_len TSRMLS_CC);
- } else {
- EX(function_state).function = zend_std_get_static_method(calling_scope, Z_TYPE_P(fci->function_name), fname, fname_len TSRMLS_CC);
- }
-
- if (((zend_internal_function*)EX(function_state).function)->handler == zend_std_call_user_call) {
- fci->object_pp = &EG(This);
- }
-
- if (check_scope_or_static && EX(function_state).function
- && !(EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)
- && !instanceof_function(check_scope_or_static, calling_scope TSRMLS_CC)) {
- zend_error(E_ERROR, "Cannot call method %R() of class %v which is not a derived from %v", Z_TYPE_P(fci->function_name), Z_UNIVAL_P(fci->function_name), calling_scope->name, check_scope_or_static->name);
- return FAILURE;
- }
- }
- }
-
- if (EX(function_state).function == NULL) {
- /* try calling __call */
- if (calling_scope && calling_scope->__call) {
- EX(function_state).function = calling_scope->__call;
- /* prepare params */
- ALLOC_INIT_ZVAL(method_name);
- ZVAL_STRINGL(method_name, fname.s, fname_len, 0);
-
- ALLOC_INIT_ZVAL(params_array);
- array_init(params_array);
- call_via_handler = 1;
- } else {
- if (old_func_name) {
- efree(Z_STRVAL_P(fci->function_name));
- Z_TYPE_P(fci->function_name) = IS_STRING;
- Z_STRVAL_P(fci->function_name) = old_func_name;
- }
- return FAILURE;
- }
- }
-
-init_fci_cache:
- if (fci_cache &&
- (EX(function_state).function->type != ZEND_INTERNAL_FUNCTION ||
- ((zend_internal_function*)EX(function_state).function)->handler != zend_std_call_user_call)
- ) {
- fci_cache->function_handler = EX(function_state).function;
- fci_cache->object_pp = fci->object_pp;
- fci_cache->calling_scope = calling_scope;
- fci_cache->called_scope = called_scope;
- fci_cache->initialized = 1;
- }
- } else {
- EX(function_state).function = fci_cache->function_handler;
- calling_scope = fci_cache->calling_scope;
- called_scope = fci_cache->called_scope;
- fci->object_pp = fci_cache->object_pp;
- EX(object) = fci->object_pp ? *fci->object_pp : NULL;
- if (fci->object_pp && *fci->object_pp && Z_TYPE_PP(fci->object_pp) == IS_OBJECT
- && (!EG(objects_store).object_buckets || !EG(objects_store).object_buckets[Z_OBJ_HANDLE_PP(fci->object_pp)].valid)) {
- return FAILURE;
- }
+ zend_fcall_info_cache fci_cache_local;
+ zval callable_name;
+ char *error = NULL;
+
+ if (!fci_cache) {
+ fci_cache = &fci_cache_local;
+ }
+
+ if (!zend_is_callable_ex(fci->function_name, fci->object_pp, IS_CALLABLE_CHECK_SILENT, &callable_name, fci_cache, &error TSRMLS_CC)) {
+ if (error) {
+ zend_error(E_WARNING, "Invalid callback %Z, %s", callable_name, error);
+ efree(error);
+ }
+ zval_dtor(&callable_name);
+ return FAILURE;
+ } else if (error) {
+ /* Capitalize the first latter of the error message */
+ if (error[0] >= 'a' && error[0] <= 'z') {
+ error[0] += ('A' - 'a');
+ }
+ zend_error(E_STRICT, "%s", error);
+ efree(error);
+ }
+ zval_dtor(&callable_name);
+ }
+
+ EX(function_state).function = fci_cache->function_handler;
+ calling_scope = fci_cache->calling_scope;
+ called_scope = fci_cache->called_scope;
+ fci->object_pp = fci_cache->object_pp;
+ EX(object) = fci->object_pp ? *fci->object_pp : NULL;
+ if (fci->object_pp && *fci->object_pp && Z_TYPE_PP(fci->object_pp) == IS_OBJECT
+ && (!EG(objects_store).object_buckets || !EG(objects_store).object_buckets[Z_OBJ_HANDLE_PP(fci->object_pp)].valid)) {
+ return FAILURE;
}
if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) {
}
}
- if (call_via_handler) {
- ZEND_VM_STACK_GROW_IF_NEEDED(2 + 1);
- } else {
- ZEND_VM_STACK_GROW_IF_NEEDED(fci->param_count + 1);
- }
+ ZEND_VM_STACK_GROW_IF_NEEDED(fci->param_count + 1);
for (i=0; i<fci->param_count; i++) {
zval *param;
Z_STRVAL_P(fci->function_name) = old_func_name;
}
- if (call_via_handler) {
- zval_ptr_dtor(&method_name);
- zval_ptr_dtor(¶ms_array);
- }
zend_error(E_WARNING, "Parameter %d to %v%s%v() expected to be a reference, value given",
i+1,
EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : EMPTY_ZSTR,
*param = **(fci->params[i]);
INIT_PZVAL(param);
}
- if (call_via_handler) {
- add_next_index_zval(params_array, param);
- } else {
- zend_vm_stack_push_nocheck(param TSRMLS_CC);
- }
- }
-
- if (call_via_handler) {
- zend_vm_stack_push_nocheck(method_name TSRMLS_CC);
- zend_vm_stack_push_nocheck(params_array TSRMLS_CC);
- fci->param_count = 2;
+ zend_vm_stack_push_nocheck(param TSRMLS_CC);
}
EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C);
}
} else {
EG(This) = NULL;
- if (calling_scope && !(EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) {
- int severity;
- char *verb;
- if (EX(function_state).function->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- severity = E_STRICT;
- verb = "should not";
- } else {
- /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- severity = E_ERROR;
- verb = "cannot";
- }
- zend_error(severity, "Non-static method %v::%v() %s be called statically", calling_scope->name, EX(function_state).function->common.function_name, verb);
- }
}
EX(prev_execute_data) = EG(current_execute_data);
EG(return_value_ptr_ptr)=original_return_value;
EG(opline_ptr) = original_opline_ptr;
} else {
+ int call_via_handler = (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
+
ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
if (EX(function_state).function->common.scope) {
EG(scope) = EX(function_state).function->common.scope;
zval_ptr_dtor(fci->retval_ptr_ptr);
*fci->retval_ptr_ptr = NULL;
}
+
+ if (call_via_handler) {
+ /* We must re-initialize function again */
+ fci_cache->initialized = 0;
+ }
}
zend_vm_stack_clear_multiple(TSRMLS_C);
- if (call_via_handler) {
- zval_ptr_dtor(&method_name);
- zval_ptr_dtor(¶ms_array);
- }
if (EG(This)) {
zval_ptr_dtor(&EG(This));
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->fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
if (UG(unicode)) {
call_user_call->function_name.u = eustrndup(method_name.u, method_len);
} else {
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->fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
if (UG(unicode)) {
call_user_call->function_name.u = eustrndup(function_name_strval.u, function_name_strlen);
} else {
callstatic_user_call->arg_info = NULL;
callstatic_user_call->num_args = 0;
callstatic_user_call->scope = ce;
- callstatic_user_call->fn_flags = ZEND_ACC_STATIC | ZEND_ACC_PUBLIC;
+ callstatic_user_call->fn_flags = ZEND_ACC_STATIC | ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER;
if (UG(unicode)) {
callstatic_user_call->function_name.u = eustrndup(function_name_strval.u, function_name_strlen);
return (zend_function *)callstatic_user_call;
} else {
- zstr class_name = ce->name;
-
- if (!class_name.v) {
- class_name.u = EMPTY_STR;
- }
- zend_error(E_ERROR, "Call to undefined method %R::%R()", type, class_name, type, function_name_strval);
+ return NULL;
}
}
efree(lc_function_name.v);
} else {
EX(fbc) = zend_std_get_static_method(ce, function_name_type, function_name_strval, function_name_strlen TSRMLS_CC);
}
+ if (!EX(fbc)) {
+ zend_error(E_ERROR, "Call to undefined method %v::%R()", ce->name, function_name_type, function_name_strval);
+ }
}
if (OP2_TYPE != IS_CONST) {
} else {
EX(fbc) = zend_std_get_static_method(ce, function_name_type, function_name_strval, function_name_strlen TSRMLS_CC);
}
+ if (!EX(fbc)) {
+ zend_error(E_ERROR, "Call to undefined method %v::%R()", ce->name, function_name_type, function_name_strval);
+ }
}
if (IS_CONST != IS_CONST) {
} else {
EX(fbc) = zend_std_get_static_method(ce, function_name_type, function_name_strval, function_name_strlen TSRMLS_CC);
}
+ if (!EX(fbc)) {
+ zend_error(E_ERROR, "Call to undefined method %v::%R()", ce->name, function_name_type, function_name_strval);
+ }
}
if (IS_TMP_VAR != IS_CONST) {
} else {
EX(fbc) = zend_std_get_static_method(ce, function_name_type, function_name_strval, function_name_strlen TSRMLS_CC);
}
+ if (!EX(fbc)) {
+ zend_error(E_ERROR, "Call to undefined method %v::%R()", ce->name, function_name_type, function_name_strval);
+ }
}
if (IS_VAR != IS_CONST) {
} else {
EX(fbc) = zend_std_get_static_method(ce, function_name_type, function_name_strval, function_name_strlen TSRMLS_CC);
}
+ if (!EX(fbc)) {
+ zend_error(E_ERROR, "Call to undefined method %v::%R()", ce->name, function_name_type, function_name_strval);
+ }
}
if (IS_UNUSED != IS_CONST) {
} else {
EX(fbc) = zend_std_get_static_method(ce, function_name_type, function_name_strval, function_name_strlen TSRMLS_CC);
}
+ if (!EX(fbc)) {
+ zend_error(E_ERROR, "Call to undefined method %v::%R()", ce->name, function_name_type, function_name_strval);
+ }
}
if (IS_CV != IS_CONST) {
} else {
EX(fbc) = zend_std_get_static_method(ce, function_name_type, function_name_strval, function_name_strlen TSRMLS_CC);
}
+ if (!EX(fbc)) {
+ zend_error(E_ERROR, "Call to undefined method %v::%R()", ce->name, function_name_type, function_name_strval);
+ }
}
if (IS_CONST != IS_CONST) {
} else {
EX(fbc) = zend_std_get_static_method(ce, function_name_type, function_name_strval, function_name_strlen TSRMLS_CC);
}
+ if (!EX(fbc)) {
+ zend_error(E_ERROR, "Call to undefined method %v::%R()", ce->name, function_name_type, function_name_strval);
+ }
}
if (IS_TMP_VAR != IS_CONST) {
} else {
EX(fbc) = zend_std_get_static_method(ce, function_name_type, function_name_strval, function_name_strlen TSRMLS_CC);
}
+ if (!EX(fbc)) {
+ zend_error(E_ERROR, "Call to undefined method %v::%R()", ce->name, function_name_type, function_name_strval);
+ }
}
if (IS_VAR != IS_CONST) {
} else {
EX(fbc) = zend_std_get_static_method(ce, function_name_type, function_name_strval, function_name_strlen TSRMLS_CC);
}
+ if (!EX(fbc)) {
+ zend_error(E_ERROR, "Call to undefined method %v::%R()", ce->name, function_name_type, function_name_strval);
+ }
}
if (IS_UNUSED != IS_CONST) {
} else {
EX(fbc) = zend_std_get_static_method(ce, function_name_type, function_name_strval, function_name_strlen TSRMLS_CC);
}
+ if (!EX(fbc)) {
+ zend_error(E_ERROR, "Call to undefined method %v::%R()", ce->name, function_name_type, function_name_strval);
+ }
}
if (IS_CV != IS_CONST) {
params[0] = &reflector_ptr;
params[1] = &output_ptr;
- ZVAL_ASCII_STRINGL(&fname, "export", sizeof("export") - 1, 1);
+ ZVAL_ASCII_STRINGL(&fname, "reflection::export", sizeof("reflection::export") - 1, 1);
fci.function_table = &reflection_ptr->function_table;
fci.function_name = &fname;
fci.object_pp = NULL;
zval_dtor(&ztmp);
}
- if (!zend_is_callable_ex(zcallable, IS_CALLABLE_STRICT, &zfunc_name, &fcc, &error TSRMLS_CC)) {
+ if (!zend_is_callable_ex(zcallable, NULL, IS_CALLABLE_STRICT, &zfunc_name, &fcc, &error TSRMLS_CC)) {
alfi.ce = fcc.calling_scope;
alfi.func_ptr = fcc.function_handler;
obj_ptr = fcc.object_pp;
return;
}
- if (!zend_is_callable_ex(zcallable, IS_CALLABLE_CHECK_SYNTAX_ONLY, &zfunc_name, &fcc, &error TSRMLS_CC)) {
+ if (!zend_is_callable_ex(zcallable, NULL, IS_CALLABLE_CHECK_SYNTAX_ONLY, &zfunc_name, &fcc, &error TSRMLS_CC)) {
zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Unable to unregister invalid function (%s)", error);
if (error) {
efree(error);
<?php exit(0); ?>
--EXPECTF--
unicode(22) "MyAutoLoader::notExist"
-Function 'MyAutoLoader::notExist' not found (class 'MyAutoLoader' does not have a method 'notexist')
+Function 'MyAutoLoader::notExist' not found (class 'MyAutoLoader' does not have a method 'notExist')
unicode(22) "MyAutoLoader::noAccess"
Function 'MyAutoLoader::noAccess' not callable (cannot access protected method MyAutoLoader::noAccess())
[1]=>
unicode(8) "notExist"
}
-Passed array does not specify an existing static method (class 'MyAutoLoader' does not have a method 'notexist')
+Passed array does not specify an existing static method (class 'MyAutoLoader' does not have a method 'notExist')
array(2) {
[0]=>
[1]=>
unicode(8) "notExist"
}
-Passed array does not specify an existing method (class 'MyAutoLoader' does not have a method 'notexist')
+Passed array does not specify an existing method (class 'MyAutoLoader' does not have a method 'notExist')
array(2) {
[0]=>
{
private $var3;
public function emptyFunction() {
- echo "defined in child";
+ echo "defined in child\n";
}
}
test(array('ChildClass', 'emptyFunction'), array(1, 2));
{
private $var4;
final function finalMethod() {
- echo "This function can't be overloaded";
+ echo "This function can't be overloaded\n";
}
}
test(array('FinalClass', 'finalMethod'), array(1, 2));
SimpleClass::square
Strict Standards: array_map() expects parameter 1 to be a valid callback, non-static method SimpleClass::square() should not be called statically in %sarray_map_object1.php on line %d
-
-Strict Standards: Non-static method SimpleClass::square() should not be called statically in %sarray_map_object1.php on line %d
-
-Strict Standards: Non-static method SimpleClass::square() should not be called statically in %sarray_map_object1.php on line %d
array(2) {
[0]=>
int(1)
ChildClass::emptyFunction
Strict Standards: array_map() expects parameter 1 to be a valid callback, non-static method ChildClass::emptyFunction() should not be called statically in %sarray_map_object1.php on line %d
-
-Strict Standards: Non-static method ChildClass::emptyFunction() should not be called statically in %sarray_map_object1.php on line %d
defined in child
-Strict Standards: Non-static method ChildClass::emptyFunction() should not be called statically in %sarray_map_object1.php on line %d
-defined in childarray(2) {
+defined in child
+array(2) {
[0]=>
NULL
[1]=>
FinalClass::finalMethod
Strict Standards: array_map() expects parameter 1 to be a valid callback, non-static method FinalClass::finalMethod() should not be called statically in %sarray_map_object1.php on line %d
-
-Strict Standards: Non-static method FinalClass::finalMethod() should not be called statically in %sarray_map_object1.php on line %d
This function can't be overloaded
-Strict Standards: Non-static method FinalClass::finalMethod() should not be called statically in %sarray_map_object1.php on line %d
-This function can't be overloadedarray(2) {
+This function can't be overloaded
+array(2) {
[0]=>
NULL
[1]=>
}
-- accessing child method from parent class --
-Warning: array_map() expects parameter 1 to be a valid callback, class 'ParentClass' does not have a method 'staticchild' in %s on line %d
+Warning: array_map() expects parameter 1 to be a valid callback, class 'ParentClass' does not have a method 'staticChild' in %s on line %d
NULL
-- accessing parent method using child class object --
array(3) {
}
-- accessing child method using parent class object --
-Warning: array_map() expects parameter 1 to be a valid callback, class 'ParentClass' does not have a method 'staticchild' in %s on line %d
+Warning: array_map() expects parameter 1 to be a valid callback, class 'ParentClass' does not have a method 'staticChild' in %s on line %d
NULL
Done
--EXPECTF--
Base::__construct(1)
Base::__construct(2)
-
-Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method Base::__construct() cannot be called statically, assuming $this from compatible context Derived_3 in %s on line %d
Base::__construct(3)
-
-Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method Base::__construct() cannot be called statically, assuming $this from compatible context Derived_4 in %s on line %d
Base::__construct(4)
-
-Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method Base::__construct() cannot be called statically, assuming $this from compatible context Derived_5 in %s on line %d
Base::__construct(5)
-
-Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method Base::__construct() cannot be called statically, assuming $this from compatible context Derived_6 in %s on line %d
Base::__construct(6)
===DONE===
A
===FOREIGN===
parent|who
-
-Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method O::who() should not be called statically, assuming $this from compatible context P in %s on line %d
O
P|parent::who
-
-Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method O::who() should not be called statically, assuming $this from compatible context P in %s on line %d
O
$this|O::who
O