1 PHP_FUNCTION(array_combine) 2 { 3 HashTable *values, *keys; 4 uint32_t pos_values = 0; 5 zval *entry_keys, *entry_values; 6 int num_keys, num_values; 7 8 // 创建一个数组,用一个数组的值作为其键名,另一个数组的值作为其值 9 if (zend_parse_parameters(ZEND_NUM_ARGS(), "hh", &keys, &values) == FAILURE) { 10 return; 11 } 12 13 // 第一个数组的元素个数 14 num_keys = zend_hash_num_elements(keys); 15 // 第二个数组的元素个数 16 num_values = zend_hash_num_elements(values); 17 18 // 两个数组的元素个数必须一致 19 if (num_keys != num_values) { 20 php_error_docref(NULL, E_WARNING, "Both parameters should have an equal number of elements"); 21 RETURN_FALSE; 22 } 23 24 // 初始化返回值(数组) 25 array_init_size(return_value, num_keys); 26 27 // 空数组,函数中止 28 if (!num_keys) { 29 return; 30 } 31 // 循环遍历第一个数组 32 ZEND_HASH_FOREACH_VAL(keys, entry_keys) { 33 /* 通过pos_value从前向后取第一个数组和第二个数组的元素值,直到数组尾 34 * 每次取出元素后组成键值对,插入返回数组。 35 */ 36 while (1) { 37 if (pos_values >= values->nNumUsed) { 38 break; 39 } else if (Z_TYPE(values->arData[pos_values].val) != IS_UNDEF) { 40 entry_values = &values->arData[pos_values].val; 41 if (Z_TYPE_P(entry_keys) == IS_LONG) { 42 entry_values = zend_hash_index_update(Z_ARRVAL_P(return_value), 43 Z_LVAL_P(entry_keys), entry_values); 44 } else { 45 zend_string *key = zval_get_string(entry_keys); 46 entry_values = zend_symtable_update(Z_ARRVAL_P(return_value), 47 key, entry_values); 48 zend_string_release(key); 49 } 50 zval_add_ref(entry_values); 51 pos_values++; 52 break; 53 } 54 pos_values++; 55 } 56 } ZEND_HASH_FOREACH_END(); 57 }