1. 程式人生 > >如何寫一個php擴充套件中深度查詢與新增的函式

如何寫一個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’];