如何写一个php扩展中深度查找与添加的函数

写扩展时经常遇到从一个多维的数组中查找元素,或把一个元素添加到多维数组中,当维度超过3个时, 就会写出一堆代码来比较繁琐了,对于这种情况可以定义一个参数可变的函数解决

添加:
void lycitea_helpers_common_depthadd(int args,  char* types,  zval *value, zval *arr, ...) {
    va_list argptr;
    va_start(argptr, arr);
    char *next_char;
    int i = 0, next_int;
    zval *pzval = arr, *val = NULL;
    while (i < args) {
        if(*types == 'l'){
            next_int = va_arg(argptr, int);
            val = zend_hash_index_find(Z_ARRVAL_P(pzval), next_int);
        }else{
            next_char = va_arg(argptr, char*);
            val = zend_hash_str_find(Z_ARRVAL_P(pzval), next_char, strlen(next_char));
        }
        if(NULL != val){
            pzval = val;
        }else if(i < (args - 1)){
            zval emptyArr;
            array_init(&emptyArr);
            if(*types == 'l'){
                add_index_zval(pzval, next_int, &emptyArr);
                pzval = zend_hash_index_find(Z_ARRVAL_P(pzval), next_int);
            }else{
                add_assoc_zval(pzval, next_char, &emptyArr);
                pzval = zend_hash_str_find(Z_ARRVAL_P(pzval), next_char, strlen(next_char));
            }
        }
        i++;
        types++;
    }
    va_end(argptr);
    if(NULL != val){
        ZVAL_COPY_VALUE(pzval, value);
        return;
    }
    types--;
    if(*types == 'l'){
        add_index_zval(pzval, next_int, value);
    }else{
        add_assoc_zval(pzval, next_char, value);
    }
}

使用示例
lycitea_helpers_common_depthadd(3, “ssl”, handler, arr, “abc” , “def”, 0);
第一个参数:参数个数,第二个:参数类型 s(字符串)l(整型),第三个:要插入的值,第四个:要插入的数组,后面都是 ssl 分别对应的值 作为key
对应php中的结构:$arr[‘abc’][‘def’][0] = ‘handler’;

查找:
zval lycitea_helpers_common_depthfind(int args,  char* types, zval * const arr, ...) {
    va_list argptr;
    va_start(argptr, arr);
    char *next_char;
    int i = 0, next_int;
    zval *pzval = arr;
    while (i < args) {
        if(NULL != pzval && IS_ARRAY == Z_TYPE_P(pzval)){
            if(*types == 'l'){
                next_int = va_arg(argptr, int);
                pzval = zend_hash_index_find(Z_ARRVAL_P(pzval), next_int);
            }else{
                next_char = va_arg(argptr, char*);
                pzval = zend_hash_str_find(Z_ARRVAL_P(pzval), next_char, strlen(next_char));
            }
        }
        if (NULL == pzval || IS_UNDEF == Z_TYPE_P(pzval)) {
            break;
        }
        i++;
        types++;
    }
    va_end(argptr);
    if (NULL == pzval || IS_UNDEF == Z_TYPE_P(pzval)) {
        zval rtn;
        ZVAL_NULL(&rtn);
        return rtn;
    }
    return *pzval;
}

使用示例:lycitea_helpers_common_depthfind(3, “lss”, arr, 0, “abc”, “def”);
第三个参数就是要查找的数组,其余的和添加雷同
对应PHP中的结构: $arr[0][‘abc’][‘def’];

猜你喜欢

转载自blog.csdn.net/weixin_43923141/article/details/85213025