diff options
Diffstat (limited to 'zend')
-rw-r--r-- | zend/callable.cpp | 51 | ||||
-rw-r--r-- | zend/classimpl.h | 2 | ||||
-rw-r--r-- | zend/extensionimpl.cpp | 4 | ||||
-rw-r--r-- | zend/globals.cpp | 2 | ||||
-rw-r--r-- | zend/namespace.cpp | 8 | ||||
-rw-r--r-- | zend/object.cpp | 4 | ||||
-rw-r--r-- | zend/stringmember.h | 4 | ||||
-rw-r--r-- | zend/super.cpp | 4 | ||||
-rw-r--r-- | zend/value.cpp | 61 |
9 files changed, 104 insertions, 36 deletions
diff --git a/zend/callable.cpp b/zend/callable.cpp index 96f5f90..a85ab72 100644 --- a/zend/callable.cpp +++ b/zend/callable.cpp @@ -31,27 +31,40 @@ void Callable::invoke(INTERNAL_FUNCTION_PARAMETERS) // uncover the hidden pointer inside the function name Callable *callable = HiddenPointer<Callable>(name); - // construct parameters - ParametersImpl params(this_ptr, ZEND_NUM_ARGS() TSRMLS_CC); - - // the function could throw an exception - try + // check if sufficient parameters were passed (for some reason this check + // is not done by Zend, so we do it here ourselves) + if (ZEND_NUM_ARGS() < callable->_required) { - // get the result - Value result(callable->invoke(params)); - - // detach the zval (we don't want it to be destructed) - zval *val = result.detach(); - - // @todo php 5.6 has a RETVAL_ZVAL_FAST macro that can be used instead (and is faster) - - // return a full copy of the zval, and do not destruct it - RETVAL_ZVAL(val, 1, 0); + // PHP itself only generates a warning when this happens, so we do the same too + Php::warning << name << "() expects at least " << callable->_required << " parameters, " << ZEND_NUM_ARGS() << " given" << std::flush; + + // and we return null + RETURN_NULL(); } - catch (Exception &exception) + else { - // process the exception - process(exception TSRMLS_CC); + // construct parameters + ParametersImpl params(this_ptr, ZEND_NUM_ARGS() TSRMLS_CC); + + // the function could throw an exception + try + { + // get the result + Value result(callable->invoke(params)); + + // detach the zval (we don't want it to be destructed) + zval *val = result.detach(); + + // @todo php 5.6 has a RETVAL_ZVAL_FAST macro that can be used instead (and is faster) + + // return a full copy of the zval, and do not destruct it + RETVAL_ZVAL(val, 1, 0); + } + catch (Exception &exception) + { + // process the exception + process(exception TSRMLS_CC); + } } } @@ -94,7 +107,7 @@ void Callable::initialize(zend_arg_info *info, const char *classname) const // because we do not support returning references in PHP-CPP, although Zend // engine allows it. Inside the name we hide a pointer to the current object finfo->_name = _ptr; - finfo->_name_len = strlen(_ptr); + finfo->_name_len = ::strlen(_ptr); finfo->_class_name = classname; // number of required arguments, and the expected return type diff --git a/zend/classimpl.h b/zend/classimpl.h index febdbca..ec28322 100644 --- a/zend/classimpl.h +++ b/zend/classimpl.h @@ -408,7 +408,7 @@ public: void property(const char *name, bool value, int flags = Php::Public) { _members.push_back(std::make_shared<BoolMember> (name, value, flags & PropertyModifiers)); } void property(const char *name, char value, int flags = Php::Public) { _members.push_back(std::make_shared<StringMember> (name, &value, 1, flags & PropertyModifiers)); } void property(const char *name, const std::string &value, int flags = Php::Public) { _members.push_back(std::make_shared<StringMember> (name, value, flags & PropertyModifiers)); } - void property(const char *name, const char *value, int flags = Php::Public) { _members.push_back(std::make_shared<StringMember> (name, value, strlen(value), flags & PropertyModifiers)); } + void property(const char *name, const char *value, int flags = Php::Public) { _members.push_back(std::make_shared<StringMember> (name, value, ::strlen(value), flags & PropertyModifiers)); } void property(const char *name, double value, int flags = Php::Public) { _members.push_back(std::make_shared<FloatMember> (name, value, flags & PropertyModifiers)); } /** diff --git a/zend/extensionimpl.cpp b/zend/extensionimpl.cpp index 545b590..0308c63 100644 --- a/zend/extensionimpl.cpp +++ b/zend/extensionimpl.cpp @@ -273,7 +273,7 @@ zend_module_entry *ExtensionImpl::module() int i = 0; // apply a function to each function - _data->apply([&i, entries](const std::string &prefix, Function &function) { + _data->functions([&i, entries](const std::string &prefix, Function &function) { // initialize the function function.initialize(prefix, &entries[i]); @@ -302,7 +302,7 @@ zend_module_entry *ExtensionImpl::module() void ExtensionImpl::initialize(TSRMLS_D) { // we need to register each class, find out all classes - _data->apply([TSRMLS_C](const std::string &prefix, ClassBase &c) { + _data->classes([TSRMLS_C](const std::string &prefix, ClassBase &c) { // forward to implementation class c.implementation()->initialize(&c, prefix TSRMLS_CC); diff --git a/zend/globals.cpp b/zend/globals.cpp index 8132ef3..5299c90 100644 --- a/zend/globals.cpp +++ b/zend/globals.cpp @@ -43,7 +43,7 @@ Global Globals::operator[](const char *name) TSRMLS_FETCH(); // check if the variable already exists - if (zend_hash_find(&EG(symbol_table), name, strlen(name)+1, (void**)&varvalue) == FAILURE) + if (zend_hash_find(&EG(symbol_table), name, ::strlen(name)+1, (void**)&varvalue) == FAILURE) { // the variable does not already exist, return a global object // that will automatically set the value when it is updated diff --git a/zend/namespace.cpp b/zend/namespace.cpp index e9ec631..8b97c52 100644 --- a/zend/namespace.cpp +++ b/zend/namespace.cpp @@ -85,13 +85,13 @@ Namespace &Namespace::add(const char *name, const native_callback_3 &function, c * * @param callback */ -void Namespace::apply(const std::function<void(const std::string &ns, Function &func)> &callback) +void Namespace::functions(const std::function<void(const std::string &ns, Function &func)> &callback) { // loop through the functions, and apply the callback for (auto &function : _functions) callback(_name, *function); // loop through the other namespaces - for (auto &ns : _namespaces) ns->apply([this, callback](const std::string &ns, Function &func) { + for (auto &ns : _namespaces) ns->functions([this, callback](const std::string &ns, Function &func) { // if this is the root namespace, we don't have to change the prefix if (_name.size() == 0) return callback(ns, func); @@ -110,13 +110,13 @@ void Namespace::apply(const std::function<void(const std::string &ns, Function & * * @param callback */ -void Namespace::apply(const std::function<void(const std::string &ns, ClassBase &clss)> &callback) +void Namespace::classes(const std::function<void(const std::string &ns, ClassBase &clss)> &callback) { // loop through the classes, and apply the callback for (auto &c : _classes) callback(_name, *c); // loop through the other namespaces - for (auto &ns : _namespaces) ns->apply([this, callback](const std::string &ns, ClassBase &clss) { + for (auto &ns : _namespaces) ns->classes([this, callback](const std::string &ns, ClassBase &clss) { // if this is the root namespace, we don't have to change the prefix if (_name.size() == 0) return callback(ns, clss); diff --git a/zend/object.cpp b/zend/object.cpp index d7fc158..08553b5 100644 --- a/zend/object.cpp +++ b/zend/object.cpp @@ -33,7 +33,7 @@ Object::Object(const char *name, Base *base) // this is a brand new object that should be allocated, the C++ instance // is already there (created by the extension) but it is not yet stored // in PHP, find out the classname first - auto *entry = zend_fetch_class(name, strlen(name), 0 TSRMLS_CC); + auto *entry = zend_fetch_class(name, ::strlen(name), 0 TSRMLS_CC); if (!entry) throw Php::Exception(std::string("Unknown class name ") + name); // construct an implementation (this will also set the implementation @@ -55,7 +55,7 @@ void Object::instantiate(const char *name) TSRMLS_FETCH(); // convert the name into a class_entry - auto *entry = zend_fetch_class(name, strlen(name), 0 TSRMLS_CC); + auto *entry = zend_fetch_class(name, ::strlen(name), 0 TSRMLS_CC); if (!entry) throw Php::Exception(std::string("Unknown class name ") + name); // initiate the zval (which was already allocated in the base constructor) diff --git a/zend/stringmember.h b/zend/stringmember.h index e58cd3d..05fdb11 100644 --- a/zend/stringmember.h +++ b/zend/stringmember.h @@ -1,7 +1,7 @@ /** * StringMember.h * - * Implementation for a property that is initially set to a strnig value + * Implementation for a property that is initially set to a string value * * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> * @copyright 2013 Copernica BV @@ -40,7 +40,7 @@ public: * @param value * @param flags */ - StringMember(const char *name, const char *value, int flags) : StringMember(name, value, strlen(value), flags) {} + StringMember(const char *name, const char *value, int flags) : StringMember(name, value, ::strlen(value), flags) {} /** * Constructor diff --git a/zend/super.cpp b/zend/super.cpp index 506d4a5..c25efeb 100644 --- a/zend/super.cpp +++ b/zend/super.cpp @@ -34,7 +34,7 @@ Value Super::operator[](const std::string &key) TSRMLS_FETCH(); // call zend_is_auto_global to ensure that the just-in-time globals are loaded - if (_name) { zend_is_auto_global(_name, strlen(_name) TSRMLS_CC); _name = nullptr; } + if (_name) { zend_is_auto_global(_name, ::strlen(_name) TSRMLS_CC); _name = nullptr; } // create a value object that wraps around the actual zval Value value(PG(http_globals)[_index]); @@ -55,7 +55,7 @@ Value Super::operator[](const char *key) TSRMLS_FETCH(); // call zend_is_auto_global to ensure that the just-in-time globals are loaded - if (_name) { zend_is_auto_global(_name, strlen(_name) TSRMLS_CC); _name = nullptr; } + if (_name) { zend_is_auto_global(_name, ::strlen(_name) TSRMLS_CC); _name = nullptr; } // create a value object that wraps around the actual zval Value value(PG(http_globals)[_index]); diff --git a/zend/value.cpp b/zend/value.cpp index 2ca1585..dd371b9 100644 --- a/zend/value.cpp +++ b/zend/value.cpp @@ -126,7 +126,7 @@ Value::Value(const char *value, int size) { // create a string zval MAKE_STD_ZVAL(_val); - ZVAL_STRINGL(_val, value, size < 0 ? strlen(value) : size, 1); + ZVAL_STRINGL(_val, value, size < 0 ? ::strlen(value) : size, 1); } /** @@ -1640,7 +1640,7 @@ bool Value::contains(int index) const bool Value::contains(const char *key, int size) const { // calculate size - if (size < 0) size = strlen(key); + if (size < 0) size = ::strlen(key); // deal with arrays if (isArray()) @@ -1704,7 +1704,7 @@ Value Value::get(const char *key, int size) const if (!isArray() && !isObject()) return Value(); // calculate size - if (size < 0) size = strlen(key); + if (size < 0) size = ::strlen(key); // are we in an object or an array? if (isArray()) @@ -1841,6 +1841,51 @@ void Value::set(const char *key, int size, const Value &value) } /** + * Unset a member by its index + * @param index + */ +void Value::unset(int index) +{ + // only necessary for arrays + if (!isArray()) return; + + // if this is not a reference variable, we should detach it to implement copy on write + SEPARATE_ZVAL_IF_NOT_REF(&_val); + + // remove the index + zend_hash_index_del(Z_ARRVAL_P(_val), index); +} + +/** + * Unset by key name and length of the key + * @param key + * @param size + */ +void Value::unset(const char *key, int size) +{ + // is this an object? + if (isObject()) + { + // if this is not a reference variable, we should detach it to implement copy on write + SEPARATE_ZVAL_IF_NOT_REF(&_val); + + // we need the tsrm_ls variable + TSRMLS_FETCH(); + + // in the zend header files, unsetting properties is redirected to setting it to null... + add_property_null_ex(_val, key, size TSRMLS_CC); + } + else if (isArray()) + { + // if this is not a reference variable, we should detach it to implement copy on write + SEPARATE_ZVAL_IF_NOT_REF(&_val); + + // remove the index + zend_hash_del(Z_ARRVAL_P(_val), key, size); + } +} + +/** * Array access operator * This can be used for accessing arrays * @param index @@ -1852,6 +1897,16 @@ HashMember<int> Value::operator[](int index) } /** + * Index by other value object + * @param key + * @return HashMember<std::string> + */ +HashMember<Value> Value::operator[](const Value &key) +{ + return HashMember<Value>(this, key); +} + +/** * Array access operato * This can be used for accessing associative arrays * @param key |