PHP_FUNCTION(array_chunk)
{
int argc = ZEND_NUM_ARGS(), num_in;
zend_long size, current = ;
zend_string *str_key;
zend_ulong num_key;
zend_bool preserve_keys = ;
zval *input = NULL;
zval chunk;
zval *entry; if (zend_parse_parameters(argc, "al|b", &input, &size, &preserve_keys) == FAILURE) {
return;
}
/* Do bounds checking for size parameter. */
/* 如果 size 小于 1,会抛出一个 E_WARNING 错误并返回 NULL。 */
if (size < ) {
php_error_docref(NULL, E_WARNING, "Size parameter expected to be greater than 0");
return;
} /* 原数组大小 */
num_in = zend_hash_num_elements(Z_ARRVAL_P(input)); /* 1 <= size <= num_in */
if (size > num_in) {
size = num_in > ? num_in : ;
} /* 初始化返回值 ((num_in - 1) / size) + 1)个元素 */
array_init_size(return_value, (uint32_t)(((num_in - ) / size) + )); // 设置(zval).u1.type_info = IS_UNDEF
// chunk保存分块后的每个数组
ZVAL_UNDEF(&chunk); ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, str_key, entry) {
/* If new chunk, create and initialize it. */
// 类型位IS_UNDEF表明,这个chunk是一个新的分块
if (Z_TYPE(chunk) == IS_UNDEF) {
// 初始化chunk数组,大小为size
array_init_size(&chunk, (uint32_t)size);
} /* Add entry to the chunk, preserving keys if necessary. */
// 是否保存原数组中的键名
if (preserve_keys) {
if (str_key) {
entry = zend_hash_update(Z_ARRVAL(chunk), str_key, entry);
} else {
entry = zend_hash_index_update(Z_ARRVAL(chunk), num_key, entry);
}
} else { // 不保存原数组中的键名,重新索引
// 数组元素插入chunk
entry = zend_hash_next_index_insert(Z_ARRVAL(chunk), entry);
}
zval_add_ref(entry); /* If reached the chunk size, add it to the result array, and reset the
* pointer. */
/*chunk大小达到size之后,将chunk加入到返回值数组return_value中,也就是一个分块完成。
* 然后重置chunk为IS_UNDEF。
*/
if (!(++current % size)) {
// chunk加入到return_value
add_next_index_zval(return_value, &chunk);
// 重置chunk
ZVAL_UNDEF(&chunk);
}
} ZEND_HASH_FOREACH_END(); /* Add the final chunk if there is one. */
/* 最后一个数组分块大小达不到size的时候, 将其加到return_value */
if (Z_TYPE(chunk) != IS_UNDEF) {
add_next_index_zval(return_value, &chunk);
}
}

php内置函数分析之array_chunk()的更多相关文章

  1. map内置函数分析所得到的思路

    map:会根据提供的函数对指定序列做映射. map(func, *iterables) --> map object Make an iterator that computes the fun ...

  2. php内置函数分析之array_diff_assoc()

    static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_type) /* {{{ */ { uint ...

  3. php内置函数分析之array_combine()

    PHP_FUNCTION(array_combine) { HashTable *values, *keys; uint32_t pos_values = ; zval *entry_keys, *e ...

  4. php内置函数分析之ucwords()

    PHP_FUNCTION(ucwords) { zend_string *str; char *delims = " \t\r\n\f\v"; register char *r, ...

  5. php内置函数分析之strtoupper()、strtolower()

    strtoupper(): PHP_FUNCTION(strtoupper) { zend_string *str; ZEND_PARSE_PARAMETERS_START(, ) Z_PARAM_S ...

  6. php内置函数分析之ucfirst()、lcfirst()

    ucfirst($str) 将 str 的首字符(如果首字符是字母)转换为大写字母,并返回这个字符串. 源码位于 ext/standard/string.c /* {{{ php_ucfirst Up ...

  7. php内置函数分析之trim()

    官方手册中: 类似函数还有两个:ltrim() 和 rtrim().分别处理字符串的左侧.右侧. trim()的具体实现位于:ext/standard/string.c /* {{{ proto st ...

  8. php内置函数分析之str_pad()

    PHP_FUNCTION(str_pad) { /* Input arguments */ zend_string *input; /* Input string 输入字符串*/ zend_long ...

  9. php内置函数分析之array_fill_keys()

    PHP_FUNCTION(array_fill_keys) { zval *keys, *val, *entry; if (zend_parse_parameters(ZEND_NUM_ARGS(), ...

随机推荐

  1. python 调用c++类方法(1)

    myTest.cpp: #include<iostream> #include<vector> class MyTest { public: MyTest(); ~MyTest ...

  2. python2与3自由切换

    Ubuntu-.04Python2与Python3自由切换 阅读目录(Content) 一.配置ssh链接 二.安装Python3及pip3 三.将Python3设置为默认 python2切换pyth ...

  3. 线性时间求取第 K 大数

    求 Top K 的算法主要有基于快速排序的和基于堆的这两种,它们的时间复杂度都为 \(O(nlogK)\).借助于分治思想,以及快速排序的区间划分,我们可以做到 \(O(n)\) 时间复杂度.具体算法 ...

  4. 1、Electron入门HelloWorld案例

    一.Electron是什么? 官网:https://electronjs.org/ Electron是由Github开发,用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开源库. ...

  5. Linux_OpenSSH远程连接

    目录 目录 SSH server SSH服务属性 SSH协议执行原理 SSH连接方式 ssh Commands scp commands sftp commands SSH在生产环境中的使用 系统间备 ...

  6. MariaDB增删改

    1.MariaDB 数据类型 MariaDB数据类型可以分为数字,日期和时间以及字符串值. 使用数据类型的原则:够用就行, 尽量使用范围小的,而不用大的 常用的数据类型: 1.整数:int, bit( ...

  7. unlink- ctf-stkof

    stkof 程序下载:https://pan.baidu.com/s/1_dcm8OFjhKbKYWa3WBtAiQ 提取码:pkyb unlink 基础操作 # define unlink #def ...

  8. cocos2dx基础篇(8) 开关按钮CCControlSwitch

    [3.x] (1)去掉 “CC” (2)对象类 CCObject 改为 Ref (3)标签类 LabelTTF 改为 Label (4)CCControlEvent 改为强枚举 Control::Ev ...

  9. 03Java面试题-------------中科软

    1.String是最基本的数据类型吗?String和StringBuffer的区别? 不是.Java中的基本数据类型只有8个:byte,short,int,long,float,double,char ...

  10. 机器学习实战-Logistics回归

    Logistics回归:实战,有两个特征X0,X1.100个样本,进行Logistics回归 1.导入数据 def load_data_set(): """ 加载数据集 ...