php内置函数分析之array_combine()

 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 }

猜你喜欢

转载自www.cnblogs.com/natian-ws/p/9148238.html