diff options
author | andot <mabingyao@gmail.com> | 2014-07-10 13:06:22 +0800 |
---|---|---|
committer | andot <mabingyao@gmail.com> | 2014-07-10 13:06:22 +0800 |
commit | b6cc95e9a96edf3a1733c4f562d42eed79dd8946 (patch) | |
tree | b3e8e711ec17ef33699c1d2679da9560d7cf93c4 /zend/value.cpp | |
parent | 28578382589dab25ea5fbd35b7754687706abc07 (diff) |
Add Php::is_a implementation.
Add is, isSubClassOf for Php::Value.
Add Php::is_a implementation.
Add Php::is_subclass_of implementation.
Diffstat (limited to 'zend/value.cpp')
-rw-r--r-- | zend/value.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/zend/value.cpp b/zend/value.cpp index 9a1a5db..38a0425 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 |