how to convert zval to vector for php extension?
Asked Answered
S

1

6

i'm writing a php extension for my c++ library which is defined something like this:

bool getPids(map<string,string> pidsMap, vector<string> ids);

now, i'm writing a php wrapper for above function like this.

ZEND_METHOD(myFInfo, get_pids)
{
    zval *idsArray;

    if (zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "a",
                                &idsArray ) == FAILURE )
    {
        RETURN_NULL();
    }
}

now i want to call getPids(), but i don't know the proper way to pass idsArray as vector into the c++ function.

after some search on web, i found an example where zval array is iterated to read each values, and i thought maybe i can use this to create a vector.

PHP_FUNCTION(hello_array_strings)
{
    zval *arr, **data;
    HashTable *arr_hash;
    HashPosition pointer;
    int array_count;
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) {
        RETURN_NULL();
    }

arr_hash = Z_ARRVAL_P(arr);
array_count = zend_hash_num_elements(arr_hash);

php_printf("The array passed contains %d elements", array_count);

for(zend_hash_internal_pointer_reset_ex(arr_hash, &pointer); zend_hash_get_current_data_ex(arr_hash, (void**) &data, &pointer) == SUCCESS; 

zend_hash_move_forward_ex(arr_hash, &pointer)) {

            if (Z_TYPE_PP(data) == IS_STRING) {
                PHPWRITE(Z_STRVAL_PP(data), Z_STRLEN_PP(data));
                php_printf("
    ");
            }
        }
        RETURN_TRUE;
    }

but is this the best approach? or is there a better way to do this?

thanks!

Streamline answered 6/8, 2012 at 18:49 Comment(0)
E
3

To populate a std::vector<std::string> from a PHP array, here's how I'd do it (the short version):

std::vector<std::string> vec;
HashTable *arr_hash = Z_ARRVAL_P(arr);
zval **arr_value;
for(zend_hash_internal_pointer_reset(arr_hash);
    zend_hash_get_current_data(arr_hash, (void **)&arr_value) == SUCCESS;
    zend_hash_move_forward(arr_hash))
{
    vec.push_back(Z_STRVAL_PP(arr_value));
}

...where arr is your input zval *, and vec is your output vector.

Eam answered 6/8, 2012 at 20:4 Comment(2)
thanks. that's what i ended up doing. i first used while loop, but for loop reduced at least 2 lines so i went with for loop.Streamline
@Prod You should accept this answer if it solved your problem by clicking the green checkmark to the left of the answer.Lamarckian

© 2022 - 2024 — McMap. All rights reserved.