summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-01 20:04:19 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-01 20:04:19 +0100
commitabc3b4fbf996a647bcefb02e4ecf643b659577c9 (patch)
tree1e3f8d37cb42f9d5c3a3caddd92224dc7807d1a5
parenta05b25d54df9d42a8fe4632073538ba47eb710ab (diff)
array access operators can now be used to access array properties
-rw-r--r--Examples/CppClassesInPhp/cppclassinphp.cpp11
-rw-r--r--src/value.cpp57
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;
}