summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Examples/CppClassesInPhp/check_map.php63
-rw-r--r--Examples/CppClassesInPhp/cppclassinphp.cpp18
-rw-r--r--src/value.cpp113
3 files changed, 95 insertions, 99 deletions
diff --git a/Examples/CppClassesInPhp/check_map.php b/Examples/CppClassesInPhp/check_map.php
new file mode 100644
index 0000000..cdd5345
--- /dev/null
+++ b/Examples/CppClassesInPhp/check_map.php
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * For functionality testing. You can then delete.
+ *
+ */
+
+class cl1 {
+ public $qwe = 45615;
+ public $asd = "asdasdasd";
+ public $zxcv = "Привет!"; // check UTF-8 chars
+ public function fn($a) {
+ echo $a;
+ }
+ function __destruct(){
+ echo 'cl1::__destruct';
+ }
+
+ function __toString() {
+ return 'I\'m class cl1';
+ }
+
+}
+
+class emptyClass {}
+
+$arr = array(
+ 'qwe' => 'qweqweqweqw',
+ 'asd' => 'Привет!', // check UTF-8 chars
+ 'zxccvx' => 'sdfsecvyh6bug6yfty',
+ 1=>2,
+ '2'=>2,
+ 44,
+ new cl1(),
+ '%'=>'%$%$%',
+ );
+//$arr = array(5,17,'qwe' => 'qweqweqweqw',4=>88,'17'=>'170','1'=>4, new cl1());
+//$arr = array(3.14,2.7,11,0,500);
+//$arr = array();
+//$arr = new cl1();
+
+$q = new MyClass();
+
+var_export($arr);
+
+//$q->loopArray($arr);
+
+// Works for objects and arrays
+$q->loopObject($arr);
+
+$q->loopObject(new emptyClass());
+
+
+/*
+// Validation removal (i.e. do I need to use zval_add_ref(value);)
+echo "\nunset(\$arr):";
+unset($arr);
+echo "\nunset(\$q):";
+unset($q);
+*/
+
+
+
diff --git a/Examples/CppClassesInPhp/cppclassinphp.cpp b/Examples/CppClassesInPhp/cppclassinphp.cpp
index 400d942..9a4e130 100644
--- a/Examples/CppClassesInPhp/cppclassinphp.cpp
+++ b/Examples/CppClassesInPhp/cppclassinphp.cpp
@@ -51,6 +51,17 @@ public:
{
return 33;
}
+
+ void loop(Php::Parameters &params)
+ {
+ std::cout << "Array/Object contains " << params[0].size() << " items" << std::endl;
+ auto m = params[0].mapValue();
+
+ std::cout << "map contains " << m.size() << " items" << std::endl;
+ for(auto &i: m) {
+ std::cout << "key: " << i.first << " \t\tval: " << i.second << std::endl;
+ }
+ }
Php::Value myMethod(Php::Parameters &params)
{
@@ -124,6 +135,13 @@ extern "C"
customClass.method("myMethod2", &MyCustomClass::myMethod);
customClass.property("property1", "prop1");
customClass.property("property2", "prop2", Php::Protected);
+
+ customClass.method("loopArray", &MyCustomClass::loop, {
+ Php::ByVal("arr", Php::Type::Array)
+ });
+ customClass.method("loopObject", &MyCustomClass::loop, {
+ Php::ByVal("obj", Php::Type::Object)
+ });
// add the class to the extension
extension.add(customClass);
diff --git a/src/value.cpp b/src/value.cpp
index 7af94fa..2c44616 100644
--- a/src/value.cpp
+++ b/src/value.cpp
@@ -1411,136 +1411,51 @@ int Value::size() const
*/
std::map<std::string,Php::Value> Value::mapValue() const
{
+ // loop through the zval key/value pairs, and return a map
// result variable
std::map<std::string,Php::Value> result;
// check type
if (isArray() || isObject())
{
-
-
- // loop through the zval key/value pairs, and return a map
-
zval **value;
char *key;
unsigned long ind;
-
// get access to the internal hash table of _val
- // Zend/zend_API.h 723
- //HashTable *arr = HASH_OF(_val);
+ // see Zend/zend_API.h 723: HASH_OF(_val)
HashTable *arr = isArray() ? Z_ARRVAL_P(_val) : Z_OBJ_HT_P(_val)->get_properties((_val) TSRMLS_CC);
- //#define HASH_OF(p) (Z_TYPE_P(p)==IS_ARRAY ? Z_ARRVAL_P(p) : ((Z_TYPE_P(p)==IS_OBJECT ? Z_OBJ_HT_P(p)->get_properties((p) TSRMLS_CC) : NULL)))
// similarly php: reset($array):
+ // The definition of this and the following functions can be found in Zend/zend_hash.h 174
// Maybe make it optional?
// If the following line to remove, then repeated calling the Value::mapValue() will return an empty map
zend_hash_internal_pointer_reset(arr);
- //HashPosition pos;
-
+ // check empty array/object
if(zend_hash_has_more_elements(arr) == FAILURE) {
return result;
}
- //while( zend_hash_has_more_elements_ex(arr, pos) != FAILURE ) {
- //while( zend_hash_has_more_elements(arr) != FAILURE ) {
- //zend_hash_get_current_key_ex(const HashTable *ht, char **str_index, uint *str_length, ulong *num_index, zend_bool duplicate, HashPosition *pos);
- /*
- #define HASH_KEY_IS_STRING 1
- #define HASH_KEY_IS_LONG 2
- #define HASH_KEY_NON_EXISTENT 3
- */
- uint r;
- //while( (r = zend_hash_get_current_key_type(arr)) != HASH_KEY_NON_EXISTENT ) {
- while( (r = zend_hash_get_current_key(arr, &key, &ind, 0)) != HASH_KEY_NON_EXISTENT ) {
-
- //zend_hash_get_current_key(arr, &key, &ind, 0);
+ unsigned int hash_key_type;
+ while( (hash_key_type = zend_hash_get_current_key(arr, &key, &ind, 0)) != HASH_KEY_NON_EXISTENT )
+ {
zend_hash_get_current_data(arr, (void **) &value);
-
-
-
- if(HASH_KEY_IS_LONG == r) {
- //result[std::to_string(ind)] = Value(*value);
- //std::cout << "std::to_string(" <<ind<< ")=" << std::to_string(ind) << std::endl;
-
- std::cout << "HASH_KEY_IS_LONG" << "\tkey:" << ind << std::endl;
+ if(HASH_KEY_IS_LONG == hash_key_type)
+ {
result[std::to_string(ind)] = Value(*value);
-
-
- } else { // HASH_KEY_IS_STRING
- std::cout << "HASH_KEY_IS_STRING" << "\tkey:" << key << std::endl;
+ }
+ else // hash_key_type == HASH_KEY_IS_STRING
+ {
result[key] = Value(*value);
}
- //std::cout << "\tkey:" << key << "\tind:" << ind << std::endl;
- //zval_add_ref(value);
+ // next iteration
zend_hash_move_forward(arr);
-
}
-
- /**
- * Wrap object around zval
- * @param zval Zval to wrap
- * @param ref Force this to be a reference
- Value(struct _zval_struct *zval, bool ref = false);
- */
-
-/*
-#define zend_hash_get_current_data(ht, pData) \
- zend_hash_get_current_data_ex(ht, pData, NULL)
-ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos);
-#define zend_hash_move_forward(ht) \
- zend_hash_move_forward_ex(ht, NULL)
-#define zend_hash_get_current_key(ht, str_index, num_index, duplicate) \
- zend_hash_get_current_key_ex(ht, str_index, NULL, num_index, duplicate, NULL)
-*/
-
-
-
-
-
-
- // Zend/zend_hash.h 174
- /*
- * traversing
- *
- #define zend_hash_has_more_elements_ex(ht, pos) \
- (zend_hash_get_current_key_type_ex(ht, pos) == HASH_KEY_NON_EXISTENT ? FAILURE : SUCCESS)
- ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos);
- ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos);
- ZEND_API int zend_hash_get_current_key_ex(const HashTable *ht, char **str_index, uint *str_length, ulong *num_index, zend_bool duplicate, HashPosition *pos);
- ZEND_API void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos);
- ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos);
- ZEND_API int zend_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosition *pos);
- *ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos);
- ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos);
- ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const char *str_index, uint str_length, ulong num_index, int mode, HashPosition *pos);
- */
-
-
-
-
-
}
- /*
- else if (isObject())
- {
- // result variable
- std::map<std::string,Php::Value> result;
-
- // @todo convert the properties to a map
-
- // done
- return result;
- }
- else
- {
- // return an empty map
- return std::map<std::string,Php::Value>();
- }
- */
+
// done
return result;
}