起个比较2的函数名叫 array_column2

 前两天在代码分享区看到一个不错的PHP函数array_column http://www.oschina.net/code/snippet_1029558_21341

  官方文档在这里 http://cn2.php.net/manual/zh/function.array-column.php,不知道那个版本会发布。但是github上已经是有代码了 https://github.com/php/php-src/blob/master/ext/standard/array.c#L2567

  尝尝鲜我们新建个扩展把官方的代码添加上去玩玩,为了避免以后函数名冲突,就把名字改为 array_column2 吧。如何快速创建一个扩展可以看我前一篇文章。

  官方实现只支持到二维数组,我在这里稍微修改HashTable的遍历函数使之递归,当然效率也降下来了!只要把对应的zend_hash_find 和 zend_hash_index_find 修改为如下即可。

static int solu_hash_find(const HashTable *ht, const char *arKey, uint nKeyLength, void **pData)
{
    ulong h;
    Bucket *p;
	
    h = zend_inline_hash_func(arKey, nKeyLength);
    for (p = ht->pListHead; p != NULL; p = p->pListNext) {
        if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
            if (!memcmp(p->arKey, arKey, nKeyLength)) {
                *pData = p->pData;
                return SUCCESS;
            }
        } else if (Z_TYPE_PP((zval **)p->pData) == IS_ARRAY) {
                return solu_hash_find(Z_ARRVAL_PP((zval **)p->pData), arKey, nKeyLength, pData);  
        }
    }
	
    return FAILURE;
}

static int solu_hash_index_find(const HashTable *ht, ulong h, void **pData)
{
    uint nIndex;
    Bucket *p;

    p = ht->arBuckets[nIndex];
    for (p = ht->pListHead; p != NULL; p = p->pListNext) {
        if ((p->h == h) && (p->nKeyLength == 0)) {
            *pData = p->pData;
            return SUCCESS;
        } else if (Z_TYPE_PP((zval **)p->pData) == IS_ARRAY) {
            return solu_hash_index_find(Z_ARRVAL_PP((zval **)p->pData), h, pData);
        }
    }

    return FAILURE;
}
效果如下:

起个比较2的函数名叫 array_column2

起个比较2的函数名叫 array_column2

其实大家应该会发现一个问题,就是test3下面的数据没有被查找到。是的,现在每个二级数组下面只会返回一个匹配值。具体原因大家看一下函数实现就知道,有兴趣的同学可以再修改修改 :)

你可能感兴趣的:(PHP,extension)