php内置函数分析之array_chunk()

 1 PHP_FUNCTION(array_chunk)
 2 {
 3     int argc = ZEND_NUM_ARGS(), num_in;
 4     zend_long size, current = 0;
 5     zend_string *str_key;
 6     zend_ulong num_key;
 7     zend_bool preserve_keys = 0;
 8     zval *input = NULL;
 9     zval chunk;
10     zval *entry;
11 
12     if (zend_parse_parameters(argc, "al|b", &input, &size, &preserve_keys) == FAILURE) {
13         return;
14     }
15     /* Do bounds checking for size parameter. */
16     /* 如果 size 小于 1,会抛出一个 E_WARNING 错误并返回 NULL。 */
17     if (size < 1) {
18         php_error_docref(NULL, E_WARNING, "Size parameter expected to be greater than 0");
19         return;
20     }
21 
22     /* 原数组大小 */
23     num_in = zend_hash_num_elements(Z_ARRVAL_P(input));
24 
25     /* 1 <= size <= num_in */
26     if (size > num_in) {
27         size = num_in > 0 ? num_in : 1;
28     }
29     
30     /* 初始化返回值 ((num_in - 1) / size) + 1)个元素 */
31     array_init_size(return_value, (uint32_t)(((num_in - 1) / size) + 1));
32 
33     // 设置(zval).u1.type_info = IS_UNDEF
34     // chunk保存分块后的每个数组
35     ZVAL_UNDEF(&chunk);
36 
37     ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, str_key, entry) {
38         /* If new chunk, create and initialize it. */
39         // 类型位IS_UNDEF表明,这个chunk是一个新的分块
40         if (Z_TYPE(chunk) == IS_UNDEF) {
41             // 初始化chunk数组,大小为size
42             array_init_size(&chunk, (uint32_t)size);
43         }
44 
45         /* Add entry to the chunk, preserving keys if necessary. */
46         // 是否保存原数组中的键名
47         if (preserve_keys) {
48             if (str_key) {
49                 entry = zend_hash_update(Z_ARRVAL(chunk), str_key, entry);
50             } else {
51                 entry = zend_hash_index_update(Z_ARRVAL(chunk), num_key, entry);
52             }
53         } else { // 不保存原数组中的键名,重新索引
54             // 数组元素插入chunk
55             entry = zend_hash_next_index_insert(Z_ARRVAL(chunk), entry);
56         }
57         zval_add_ref(entry);
58 
59         /* If reached the chunk size, add it to the result array, and reset the
60          * pointer. */
61         /*chunk大小达到size之后,将chunk加入到返回值数组return_value中,也就是一个分块完成。
62         * 然后重置chunk为IS_UNDEF。
63         */
64         if (!(++current % size)) {
65             // chunk加入到return_value
66             add_next_index_zval(return_value, &chunk);
67             // 重置chunk
68             ZVAL_UNDEF(&chunk);
69         }
70     } ZEND_HASH_FOREACH_END(); 
71 
72     /* Add the final chunk if there is one. */
73     /* 最后一个数组分块大小达不到size的时候, 将其加到return_value */
74     if (Z_TYPE(chunk) != IS_UNDEF) {
75         add_next_index_zval(return_value, &chunk);
76     }
77 }

猜你喜欢

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