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 }