diff options
Diffstat (limited to 'zend')
-rw-r--r-- | zend/includes.h | 1 | ||||
-rw-r--r-- | zend/value.cpp | 38 |
2 files changed, 39 insertions, 0 deletions
diff --git a/zend/includes.h b/zend/includes.h index 63b435e..8af557c 100644 --- a/zend/includes.h +++ b/zend/includes.h @@ -79,6 +79,7 @@ #include "../include/namespace.h" #include "../include/extension.h" #include "../include/call.h" +#include "../include/fastcall.h" /** * Common header files for internal use only diff --git a/zend/value.cpp b/zend/value.cpp index 352e90d..9b409f7 100644 --- a/zend/value.cpp +++ b/zend/value.cpp @@ -1408,6 +1408,44 @@ bool Value::isCallable() const return zend_is_callable(_val, 0, NULL TSRMLS_CC); } +bool Value::isImpl(const std::string &classname, bool allow_string, bool only_subclass) const { + /* + * allow_string - is default is false, isSubclassOf is true. + * if it's allowed, the the autoloader will be called if the class does not exist. + * default behaviour is different, as 'is' used to be used to test mixed return + * values and there is no easy way to deprecate this. + */ + // we need the tsrm_ls variable + TSRMLS_FETCH(); + + zend_class_entry *instance_ce; + zend_class_entry **ce; + + if (allow_string && isString()) { + zend_class_entry **the_ce; + if (zend_lookup_class(Z_STRVAL_P(_val), Z_STRLEN_P(_val), &the_ce TSRMLS_CC) == FAILURE) { + return false; + } + instance_ce = *the_ce; + } + else if (isObject() && HAS_CLASS_ENTRY(*_val)) { + instance_ce = Z_OBJCE_P(_val); + } + else { + return false; + } + + if (zend_lookup_class_ex(classname.c_str(), (int32_t)classname.length(), NULL, 0, &ce TSRMLS_CC) == FAILURE) { + return false; + } + + if (only_subclass && instance_ce == *ce) { + return false; + } + + return instanceof_function(instance_ce, *ce TSRMLS_CC); +} + /** * Make a clone of the type * @return Value |