• php内置函数分析之array_diff_assoc()


      1 static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_type) /* {{{ */
      2 {
      3     uint idx;
      4     Bucket *p;
      5     int argc, i;
      6     zval *args;
      7     int (*diff_data_compare_func)(zval *, zval *) = NULL;
      8     zend_bool ok;
      9     zval *val, *data;
     10 
     11     /* Get the argument count */
     12     argc = ZEND_NUM_ARGS();
     13     if (data_compare_type == DIFF_COMP_DATA_USER) {  // array_diff_uassoc
     14         if (argc < 3) {
     15             php_error_docref(NULL, E_WARNING, "at least 3 parameters are required, %d given", ZEND_NUM_ARGS());
     16             return;
     17         }
     18         // 类型描述符:f  - function or array containing php method call info (returned as zend_fcall_info and zend_fcall_info_cache)
     19         if (zend_parse_parameters(ZEND_NUM_ARGS(), "+f", &args, &argc, &BG(user_compare_fci), &BG(user_compare_fci_cache)) == FAILURE) {
     20             return;
     21         }
     22         diff_data_compare_func = zval_user_compare; // 用户自定义的回调函数
     23     } else {  
     24         // 至少两个参数
     25         if (argc < 2) {
     26             php_error_docref(NULL, E_WARNING, "at least 2 parameters are required, %d given", ZEND_NUM_ARGS());
     27             return;
     28         }
     29         if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
     30             return;
     31         }
     32         // array_diff_assoc
     33         if (data_compare_type == DIFF_COMP_DATA_INTERNAL) {
     34             diff_data_compare_func = zval_compare; //字符串比较函数
     35         }
     36     }
     37     
     38     // 参数(array_diff_uassoc时回调函数除外)必须是数组
     39     for (i = 0; i < argc; i++) {
     40         if (Z_TYPE(args[i]) != IS_ARRAY) {
     41             php_error_docref(NULL, E_WARNING, "Argument #%d is not an array", i + 1);
     42             RETURN_NULL();
     43         }
     44     }
     45 
     46     array_init(return_value);
     47     
     48     // 循环第一个数组
     49     for (idx = 0; idx < Z_ARRVAL(args[0])->nNumUsed; idx++) {
     50         p = Z_ARRVAL(args[0])->arData + idx;
     51         val = &p->val;
     52         if (Z_TYPE_P(val) == IS_UNDEF) continue; // 跳过已销毁的元素。
     53         if (UNEXPECTED(Z_TYPE_P(val) == IS_INDIRECT)) { // ???
     54             val = Z_INDIRECT_P(val);
     55             if (Z_TYPE_P(val) == IS_UNDEF) continue;
     56         }
     57         if (Z_ISREF_P(val) && Z_REFCOUNT_P(val) == 1) {
     58             ZVAL_UNREF(val);
     59         }
     60         if (p->key == NULL) { // 键为整数
     61             ok = 1;
     62             // 遍历其他数组,查找
     63             for (i = 1; i < argc; i++) {
     64                 // 键和值都要一致
     65                 if ((data = zend_hash_index_find(Z_ARRVAL(args[i]), p->h)) != NULL &&
     66                     (!diff_data_compare_func ||
     67                     diff_data_compare_func(val, data) == 0)
     68                 ) {
     69                     // 找到之后,ok置为0                    
     70                     ok = 0;
     71                     break;
     72                 }
     73             }
     74             // 没有再其他数组中找到,则将该元素(键和值)保存到return_value中
     75             if (ok) {
     76                 if (Z_REFCOUNTED_P(val)) {
     77                     Z_ADDREF_P(val);
     78                 }
     79                 zend_hash_index_update(Z_ARRVAL_P(return_value), p->h, val);
     80             }
     81         } else {  // 键为字符串
     82             ok = 1;
     83             for (i = 1; i < argc; i++) {
     84                 // 键和值都要一致
     85                 if ((data = zend_hash_find_ind(Z_ARRVAL(args[i]), p->key)) != NULL &&
     86                     (!diff_data_compare_func ||
     87                     diff_data_compare_func(val, data) == 0)
     88                 ) {
     89                     // 找到之后,ok置为0
     90                     ok = 0;
     91                     break;
     92                 }
     93             }
     94             // 没有再其他数组中找到,则将该元素(键和值)保存到return_value中
     95             if (ok) {
     96                 if (Z_REFCOUNTED_P(val)) {
     97                     Z_ADDREF_P(val);
     98                 }
     99                 zend_hash_update(Z_ARRVAL_P(return_value), p->key, val);
    100             }
    101         }
    102     }
    103 }
  • 相关阅读:
    版本控制-搭建git服务器
    借助阿里AntUI元素实现两个Web页面之间的过渡——“Loading…”
    在VS中自定义代码段
    案例研究:CopyToAsync
    与其他.Net异步模式和类型进行互操作
    使用boilerplate模版创建解决方案
    实践基于Task的异步模式
    实现基于Task的异步模式
    基于Task的异步模式的定义
    基于Task的异步模式--全面介绍
  • 原文地址:https://www.cnblogs.com/natian-ws/p/9153414.html
Copyright © 2020-2023  润新知