array.c PHP array_chunk 函数
时间:2011-06-08 来源:Jason-zy
PHP_FUNCTION(array_chunk)
{
/* argc:传入参数数量 key_type:底下获取数组key的临时变量 num_in:hashTable存储的数组长度临时变量*/
int argc = ZEND_NUM_ARGS(), key_type, num_in;
long size, current = 0;
char *str_key;
uint str_key_len;
ulong num_key;
zend_bool preserve_keys = 0;
zval *input = NULL;
zval *chunk = NULL;
zval **entry;
HashPosition pos;
/*zend_parse_parameters:解析校验传入数据
"al|b" 对应 &input, &size, &preserve_keys
a=array l=long "|"字符或的意思 b=bool
*/
if (zend_parse_parameters(argc TSRMLS_CC, "al|b", &input, &size, &preserve_keys) == FAILURE) {
return;
}
/* 如果传入的size是0报错 Do bounds checking for size parameter. */
if (size < 1) {
//php_error_docref PHP报错方法 E_WARNING错误
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Size parameter expected to be greater than 0");
return;
}
/*zend_hash_num_elements 获取hashTable 数组的长度*/
num_in = zend_hash_num_elements(Z_ARRVAL_P(input));
/*如果传入的 数量 大于 数组长度*/
if (size > num_in) {
//数组长度大于0 则新chunk 的长度就是数组的长度。反之则1
size = num_in > 0 ? num_in : 1;
}
//初始化数组长度 return_value 要返回的那个
array_init_size(return_value, ((num_in - 1) / size) + 1);
//zend_hash_internal_pointer_reset_ex pos 指向 数组第一个元素
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos);
//zend_hash_get_current_data_ex 获取当前指针指向的数据 input里面的pos位置 传给entry
while (zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void**)&entry, &pos) == SUCCESS) {
/* If new chunk, create and initialize it. */
/*判断是不是新chunk,第一是默认新的初始化是 NULL
*/
if (!chunk) {
MAKE_STD_ZVAL(chunk);//申请初始化新的容器
array_init_size(chunk, size);//初始化数组长度
}
/* Add entry to the chunk, preserving keys if necessary. */
/* zval_add_ref这个方法不知道什么意思*/
zval_add_ref(entry);
if (preserve_keys) {
//保持原来的key zend_hash_get_current_key_ex 获取key的信息
key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &str_key, &str_key_len, &num_key, 0, &pos);
switch (key_type) {
case HASH_KEY_IS_STRING:
//add_assoc_zval_ex 添加字符串key 字符串key需要长度
add_assoc_zval_ex(chunk, str_key, str_key_len, *entry);
break;
default:
//add_index_zval 数字key
add_index_zval(chunk, num_key, *entry);
break;
}
} else {
//add_next_index_zval 加入个新的key 相当于insert
add_next_index_zval(chunk, *entry);
}
/* If reached the chunk size, add it to the result array, and reset the
* pointer. */
/*新生成个数组*/
if (!(++current % size)) {
/*add_next_index_zval chunk 插入到 return_value里面*/
add_next_index_zval(return_value, chunk);
/*设置chunk为NULL 重新生成个chunk*/
chunk = NULL;
}
//指针移动到hashTable的下一个
zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos);
}
/* Add the final chunk if there is one. */
/*比如 5个的数组 分成3个 最后一个 不满足 上面的条件。追加到 return_value里面*/
if (chunk) {
add_next_index_zval(return_value, chunk);
}
}
{
/* argc:传入参数数量 key_type:底下获取数组key的临时变量 num_in:hashTable存储的数组长度临时变量*/
int argc = ZEND_NUM_ARGS(), key_type, num_in;
long size, current = 0;
char *str_key;
uint str_key_len;
ulong num_key;
zend_bool preserve_keys = 0;
zval *input = NULL;
zval *chunk = NULL;
zval **entry;
HashPosition pos;
/*zend_parse_parameters:解析校验传入数据
"al|b" 对应 &input, &size, &preserve_keys
a=array l=long "|"字符或的意思 b=bool
*/
if (zend_parse_parameters(argc TSRMLS_CC, "al|b", &input, &size, &preserve_keys) == FAILURE) {
return;
}
/* 如果传入的size是0报错 Do bounds checking for size parameter. */
if (size < 1) {
//php_error_docref PHP报错方法 E_WARNING错误
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Size parameter expected to be greater than 0");
return;
}
/*zend_hash_num_elements 获取hashTable 数组的长度*/
num_in = zend_hash_num_elements(Z_ARRVAL_P(input));
/*如果传入的 数量 大于 数组长度*/
if (size > num_in) {
//数组长度大于0 则新chunk 的长度就是数组的长度。反之则1
size = num_in > 0 ? num_in : 1;
}
//初始化数组长度 return_value 要返回的那个
array_init_size(return_value, ((num_in - 1) / size) + 1);
//zend_hash_internal_pointer_reset_ex pos 指向 数组第一个元素
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos);
//zend_hash_get_current_data_ex 获取当前指针指向的数据 input里面的pos位置 传给entry
while (zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void**)&entry, &pos) == SUCCESS) {
/* If new chunk, create and initialize it. */
/*判断是不是新chunk,第一是默认新的初始化是 NULL
*/
if (!chunk) {
MAKE_STD_ZVAL(chunk);//申请初始化新的容器
array_init_size(chunk, size);//初始化数组长度
}
/* Add entry to the chunk, preserving keys if necessary. */
/* zval_add_ref这个方法不知道什么意思*/
zval_add_ref(entry);
if (preserve_keys) {
//保持原来的key zend_hash_get_current_key_ex 获取key的信息
key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &str_key, &str_key_len, &num_key, 0, &pos);
switch (key_type) {
case HASH_KEY_IS_STRING:
//add_assoc_zval_ex 添加字符串key 字符串key需要长度
add_assoc_zval_ex(chunk, str_key, str_key_len, *entry);
break;
default:
//add_index_zval 数字key
add_index_zval(chunk, num_key, *entry);
break;
}
} else {
//add_next_index_zval 加入个新的key 相当于insert
add_next_index_zval(chunk, *entry);
}
/* If reached the chunk size, add it to the result array, and reset the
* pointer. */
/*新生成个数组*/
if (!(++current % size)) {
/*add_next_index_zval chunk 插入到 return_value里面*/
add_next_index_zval(return_value, chunk);
/*设置chunk为NULL 重新生成个chunk*/
chunk = NULL;
}
//指针移动到hashTable的下一个
zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos);
}
/* Add the final chunk if there is one. */
/*比如 5个的数组 分成3个 最后一个 不满足 上面的条件。追加到 return_value里面*/
if (chunk) {
add_next_index_zval(return_value, chunk);
}
}
相关阅读 更多 +