php内置函数分析之array_column()

 1 PHP_FUNCTION(array_column)
 2 {
 3     zval *zcolumn = NULL, *zkey = NULL, *data;
 4     HashTable *arr_hash;
 5     zval *zcolval = NULL, *zkeyval = NULL, rvc, rvk;
 6 
 7     // !如果接收了一个php语言里的null变量,则直接将其转成C语言里的NULL,而不是封装成IS_NULL类型的zval 
 8     if (zend_parse_parameters(ZEND_NUM_ARGS(), "hz!|z!", &arr_hash, &zcolumn, &zkey) == FAILURE) {
 9         return;
10     }
11 
12     /* 检查colunm和index是否有效(只能为数字和对象,对象需能转换为字符串)。
13     *  无效则报The %s key should be either a string or an integer的warning错误。
14     */
15     if ((zcolumn && !array_column_param_helper(zcolumn, "column")) ||
16         (zkey && !array_column_param_helper(zkey, "index"))) {
17         RETURN_FALSE;
18     }
19     // 初始化返回值
20     array_init(return_value);
21     // 循环遍历数组
22     ZEND_HASH_FOREACH_VAL(arr_hash, data) {
23         ZVAL_DEREF(data);
24 
25         if (!zcolumn) { // column未设置
26             zcolval = data;
27         } else if ((zcolval = array_column_fetch_prop(data, zcolumn, &rvc)) == NULL) {// 该列的值为NULL,则跳过,进入下一循环
28             continue;
29         }
30 
31         /* Failure will leave zkeyval alone which will land us on the final else block below
32          * which is to append the value as next_index
33          */
34         if (zkey) {
35             zkeyval = array_column_fetch_prop(data, zkey, &rvk); // 获取zkey对应的列,作为返回数组的键/索引
36         }
37 
38         Z_TRY_ADDREF_P(zcolval);
39         // 返回值数组:array(zkeyval=>zcolval,...)
40         if (zkeyval && Z_TYPE_P(zkeyval) == IS_STRING) {
41             zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR_P(zkeyval), zcolval);
42         } else if (zkeyval && Z_TYPE_P(zkeyval) == IS_LONG) {
43             add_index_zval(return_value, Z_LVAL_P(zkeyval), zcolval);
44         } else if (zkeyval && Z_TYPE_P(zkeyval) == IS_OBJECT) {
45             zend_string *key = zval_get_string(zkeyval);
46             zend_symtable_update(Z_ARRVAL_P(return_value), key, zcolval);
47             zend_string_release(key);
48         } else {
49             // 没有zkeyval,则返回值数组为索引数组
50             add_next_index_zval(return_value, zcolval);
51         }
52         /* 清理内存 */
53         if (zcolval == &rvc) {
54             zval_ptr_dtor(&rvc);
55         }
56         if (zkeyval == &rvk) {
57             zval_ptr_dtor(&rvk);
58         }
59     } ZEND_HASH_FOREACH_END();
60 }

 

posted @ 2018-06-07 00:08  S3c0ldW4ng  阅读(1541)  评论(0编辑  收藏  举报