diff options
author | Andrei Zmievski <andrei@php.net> | 2001-03-12 03:08:28 +0000 |
---|---|---|
committer | Andrei Zmievski <andrei@php.net> | 2001-03-12 03:08:28 +0000 |
commit | 13148b549121ca0e83f1a9e4a330763257e317c9 (patch) | |
tree | 56f909becbcde3aa064eead0db075673ee48ec3f | |
parent | d73ef1242986f84a7bb9e6fa088f19d4f22b05dc (diff) | |
download | php-git-13148b549121ca0e83f1a9e4a330763257e317c9.tar.gz |
Improve zend_is_callable() to the point where it's actually useful.
Now it just needs to be invoked everywhere in PHP where a callback is
expected.
-rw-r--r-- | Zend/zend_API.c | 63 | ||||
-rw-r--r-- | Zend/zend_API.h | 2 |
2 files changed, 53 insertions, 12 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 4a14709125..b743e0a58f 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -910,40 +910,81 @@ ZEND_API int zend_disable_function(char *function_name, uint function_name_lengt return zend_register_functions(disabled_function, CG(function_table), MODULE_PERSISTENT); } -ZEND_API zend_bool zend_is_callable(zval *function) +zend_bool zend_is_callable(zval *callable, zend_bool syntax_only, char **callable_name) { char *lcname; - zend_bool retval = 0; + int retval = 0; ELS_FETCH(); - switch (Z_TYPE_P(function)) { + switch (Z_TYPE_P(callable)) { case IS_STRING: - lcname = estrndup(Z_STRVAL_P(function), Z_STRLEN_P(function)); - zend_str_tolower(lcname, Z_STRLEN_P(function)); - if (zend_hash_exists(EG(function_table), lcname, Z_STRLEN_P(function)+1)) + if (syntax_only) + return 1; + + lcname = estrndup(Z_STRVAL_P(callable), Z_STRLEN_P(callable)); + zend_str_tolower(lcname, Z_STRLEN_P(callable)); + if (zend_hash_exists(EG(function_table), lcname, Z_STRLEN_P(callable)+1)) retval = 1; efree(lcname); + if (!retval && callable_name) + *callable_name = estrndup(Z_STRVAL_P(callable), Z_STRLEN_P(callable)); break; case IS_ARRAY: { zval **method; zval **obj; + zend_class_entry *ce; + char name_buf[1024]; + char callable_name_len; - if (zend_hash_index_find(Z_ARRVAL_P(function), 0, (void **) &obj) == SUCCESS && - zend_hash_index_find(Z_ARRVAL_P(function), 1, (void **) &method) == SUCCESS && - Z_TYPE_PP(obj) == IS_OBJECT && + if (zend_hash_index_find(Z_ARRVAL_P(callable), 0, (void **) &obj) == SUCCESS && + zend_hash_index_find(Z_ARRVAL_P(callable), 1, (void **) &method) == SUCCESS && + (Z_TYPE_PP(obj) == IS_OBJECT || Z_TYPE_PP(obj) == IS_STRING) && Z_TYPE_PP(method) == IS_STRING) { + + if (syntax_only) + return 1; + + if (Z_TYPE_PP(obj) == IS_STRING) { + int found; + + lcname = estrndup(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj)); + zend_str_tolower(lcname, Z_STRLEN_PP(obj)); + found = zend_hash_find(EG(class_table), lcname, Z_STRLEN_PP(obj) + 1, (void**)&ce); + efree(lcname); + if (found == FAILURE) { + if (callable_name) { + callable_name_len = snprintf(name_buf, 1024, "%s::%s", Z_STRVAL_PP(obj), Z_STRVAL_PP(method)); + *callable_name = estrndup(name_buf, callable_name_len); + } + break; + } + } else + ce = Z_OBJCE_PP(obj); lcname = estrndup(Z_STRVAL_PP(method), Z_STRLEN_PP(method)); zend_str_tolower(lcname, Z_STRLEN_PP(method)); - if (zend_hash_exists(&Z_OBJCE_PP(obj)->function_table, lcname, Z_STRLEN_PP(method)+1)) + if (zend_hash_exists(&ce->function_table, lcname, Z_STRLEN_PP(method)+1)) retval = 1; + if (!retval && callable_name) { + callable_name_len = snprintf(name_buf, 1024, "%s::%s", ce->name, Z_STRVAL_PP(method)); + *callable_name = estrndup(name_buf, callable_name_len); + } efree(lcname); - } + } else if (callable_name) + *callable_name = estrndup("Array", sizeof("Array")-1); } break; default: + if (callable_name) { + zval expr_copy; + int use_copy; + + zend_make_printable_zval(callable, &expr_copy, &use_copy); + *callable_name = estrndup(Z_STRVAL(expr_copy), Z_STRLEN(expr_copy)); + zval_dtor(&expr_copy); + } break; } diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 3b88d917ad..2ad161ea6b 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -120,7 +120,7 @@ ZEND_API zend_module_entry *zend_get_module(int module_number); ZEND_API int zend_disable_function(char *function_name, uint function_name_length); ZEND_API void wrong_param_count(void); -ZEND_API zend_bool zend_is_callable(zval *function); +ZEND_API zend_bool zend_is_callable(zval *callable, zend_bool syntax_only, char **callable_name); #define getThis() (this_ptr) |