diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-01 20:04:19 +0100 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-01 20:04:19 +0100 |
commit | abc3b4fbf996a647bcefb02e4ecf643b659577c9 (patch) | |
tree | 1e3f8d37cb42f9d5c3a3caddd92224dc7807d1a5 | |
parent | a05b25d54df9d42a8fe4632073538ba47eb710ab (diff) |
array access operators can now be used to access array properties
-rw-r--r-- | Examples/CppClassesInPhp/cppclassinphp.cpp | 11 | ||||
-rw-r--r-- | src/value.cpp | 57 |
2 files changed, 51 insertions, 17 deletions
diff --git a/Examples/CppClassesInPhp/cppclassinphp.cpp b/Examples/CppClassesInPhp/cppclassinphp.cpp index b13602e..ebc4969 100644 --- a/Examples/CppClassesInPhp/cppclassinphp.cpp +++ b/Examples/CppClassesInPhp/cppclassinphp.cpp @@ -45,6 +45,13 @@ public: std::cout << "_x: " << _x << std::endl; _x = params[0]; std::cout << "New _x" << _x << std::endl; + + Php::Value v = params[0]; + + std::cout << "contains: " << v.contains("bla") << std::endl; + std::cout << "value: " << v["bla"] << std::endl; + + v["something"] = "something else"; } }; @@ -74,8 +81,8 @@ extern "C" // add methods to it customClass.add("myMethod", &MyCustomClass::myMethod, Php::Final, {}); - customClass.add("property1", "bla"); - customClass.add("property2", "bla", Php::Protected); + customClass.add("property1", "prop1"); + customClass.add("property2", "prop2", Php::Protected); // add the class to the extension extension.add(customClass); diff --git a/src/value.cpp b/src/value.cpp index c948dcd..8827e6e 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -1382,8 +1382,14 @@ bool Value::contains(const char *key, int size) const } else if (isObject()) { - // @todo implementation - return false; + // retrieve the class entry + auto *entry = zend_get_class_entry(_val); + + // read the property + zval *property = zend_read_property(entry, _val, key, size, 0); + + // check if valid + return property != nullptr; } else { @@ -1440,8 +1446,14 @@ Value Value::get(const char *key, int size) const } else { - // @todo implementation for objects - return Value(); + // retrieve the class entry + auto *entry = zend_get_class_entry(_val); + + // read the property + zval *property = zend_read_property(entry, _val, key, size, 1); + + // wrap in value + return Value(property); } } @@ -1500,22 +1512,37 @@ const Value &Value::set(const char *key, int size, const Value &value) // skip if nothing is going to change if (value._val == *current) return value; } + + // 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); - // must be an array - setType(arrayType); + // retrieve the class entry + auto *entry = zend_get_class_entry(_val); - // if this is not a reference variable, we should detach it to implement copy on write - SEPARATE_ZVAL_IF_NOT_REF(&_val); + // update the property + zend_update_property(entry, _val, key, size, value._val); + } + else + { + // must be an array + setType(arrayType); + + // if this is not a reference variable, we should detach it to implement copy on write + SEPARATE_ZVAL_IF_NOT_REF(&_val); + + // add the value (this will reduce the refcount of the current value) + add_assoc_zval_ex(_val, key, size+1, value._val); + + // the variable has one more reference (the array entry) + Z_ADDREF_P(value._val); + } - // add the value (this will reduce the refcount of the current value) - add_assoc_zval_ex(_val, key, size+1, value._val); - - // the variable has one more reference (the array entry) - Z_ADDREF_P(value._val); - // object should stay valid validate(); - + // done return value; } |