Extending PHP iteration through an array

I'm starting to write a PHP extension and I just want to talk about how to iterate over the array that is being transferred (in order to change the value of the data by value). The preferred method would be a for loop so that I can map array 1 to data from array2, for example. array1 [0] is associated with array2 [0], [1] with [1], etc ...

Anyone who can help?

modarray.c

#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" extern zend_module_entry modarray_module_entry; #define phpext_modarray_ptr &modarray_module_entry PHP_FUNCTION(modarray); static function_entry modarray_functions[] = { PHP_FE(modarray, NULL) PHP_FE_END }; zend_module_entry modarray_module_entry = { STANDARD_MODULE_HEADER, "modarray", modarray_functions, NULL, NULL, NULL, NULL, NULL, "0.1", STANDARD_MODULE_PROPERTIES }; ZEND_GET_MODULE(modarray) PHP_FUNCTION(modarray) { zval *val, *val2; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &val, &val2) == FAILURE){ return; } SEPARATE_ZVAL(&val); SEPARATE_ZVAL(&val2); array_init(return_value); zval_add_ref(&val); zval_add_ref(&val2); add_next_index_zval(return_value, val); add_next_index_zval(return_value, val2); } 

PHP code

 <?php $array1 = array(1,2,3,4); $array2 = array(5,6,7,8); echo '<pre>'; print_r(modarray($array1,$array2)); echo '</pre>'; ?> 

PHP output

 Array ( [0] => Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 ) [1] => Array ( [0] => 5 [1] => 6 [2] => 7 [3] => 8 ) ) 
+6
source share
3 answers

There are two ways to do this, one complete β€œguide” using the iterative API:

 HashPosition pos; zval *collection, **arg; uint hash_key_type; uint string_key_len; ulong int_key; char *string_key = NULL; ... get the collection from somewhere, eg argument parsing ... while (!EG(exception) && zend_hash_get_current_data_ex(Z_ARRVAL_P(collection), (void **)&arg, &pos) == SUCCESS) { zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(collection), &pos); MAKE_STD_ZVAL(key); hash_key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(collection), &string_key, &string_key_len, &int_key, 0, &pos); // Invoke eg zend_hash_update zend_hash_move_forward_ex(Z_ARRVAL_P(collection), &pos); } 

The preferred alternative is to use the three zend_hash_apply*() functions with a callback, which is considered more elegant:

 static int replace_value(zval **arg, zval ****params TSRMLS_DC) { add_next_index_zval(params, val); return ZEND_HASH_APPLY_REMOVE; } zval *in, ***out; ... fill in from somewhere from somewhere, eg argument parsing ... array_init(**out); zend_hash_apply_with_argument(Z_ARRVAL_P(collection, (apply_func_arg_t) replace_value, params TSRMLS_CC); 

Note. I did not test one of the fragments locally, but I copied it from different places. So please tell me about typos, missed announcements, or dereferencing pointers. Corrections are welcome, of course!

+1
source
 function multi_diff($arr1,$arr2){ $result = array(); foreach ($arr1 as $k=>$v){ if(!isset($arr2[$k])){ $result[$k] = $v; } else { if(is_array($v) && is_array($arr2[$k])){ $diff = multi_diff($v, $arr2[$k]); if(!empty($diff)) $result[$k] = $diff; } } } return $result; } //example: var_dump(multi_diff( array( "A"=>array( "A1"=>array('A1-0','A1-1','A1-2','A1-3'), "A2"=>array('A2-0','A2-1','A2-2','A2-3'), "A3"=>array('A3-0','A3-1','A3-2','A3-3') ), "B"=>array( "B1"=>array('B1-0','B1-1','B1-2','B1-3'), "B2"=>array('B2-0','B2-1','B2-2','B2-3'), "B3"=>array('B3-0','B3-1','B3-2','B3-3') ), "C"=>array( "C1"=>array('C1-0','C1-1','C1-2','C1-3'), "C2"=>array('C2-0','C2-1','C2-2','C2-3'), "C3"=>array('C3-0','C3-1','C3-2','C3-3') ), "D"=>array( "D1"=>array('D1-0','D1-1','D1-2','D1-3'), "D2"=>array('D2-0','D2-1','D2-2','D2-3'), "D3"=>array('D3-0','D3-1','D3-2','D3-3') ) ), array( "A"=>array( "A1"=>array('A1-0','A1-1','A1-2','A1-3'), "A2"=>array('A2-0','A2-1','A2-2','A2-3'), "A3"=>array('A3-0','A3-1','A3-2') ), "B"=>array( "B1"=>array('B1-0','B1-2','B1-3'), "B2"=>array('B2-0','B2-1','B2-2','B2-3'), "B3"=>array('B3-0','B3-1','B3-3') ), "C"=>array( "C1"=>array('C1-0','C1-1','C1-2','C1-3'), ), "D"=>array( "D1"=>array('D1-0','D1-1','D1-2','D1-3'), " "C3"=>array('C3-0','C3-1') D2"=>array('D2-0','D2-1','D2-2','D2-3'), "D3"=>array('D3-0','D3-1','D3-2','D3-3') ) ) )); 
0
source

You can check the xarray or php-src extension for some C snippets: https://github.com/c9s/xarray

0
source

Source: https://habr.com/ru/post/971712/


All Articles