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 }