数组

数组

1,创建一个扩展

./ext_skel --extname=array

2,hashTable函数说明

typedef struct bucket {
    ulong h;                        /* Used for numeric indexing */
    uint nKeyLength;
    void *pData;
    void *pDataPtr;
    struct bucket *pListNext;
    struct bucket *pListLast;
    struct bucket *pNext;
    struct bucket *pLast;
    const char *arKey;
} Bucket;

typedef struct _hashtable {
    uint nTableSize;
    uint nTableMask;
    uint nNumOfElements;
    ulong nNextFreeElement;
    Bucket *pInternalPointer;   /* Used for element traversal */
    Bucket *pListHead;
    Bucket *pListTail;
    Bucket **arBuckets;
    dtor_func_t pDestructor;
    zend_bool persistent;
    unsigned char nApplyCount;
    zend_bool bApplyProtection;
    #if ZEND_DEBUG
        int inconsistent;
    #endif
} HashTable;

typedef Bucket* HashPosition; 

//初始化HashTable
HashTable *myht;
zval *zv;

/* Same as myht = emalloc(sizeof(HashTable)); */
ALLOC_HASHTABLE(myht); 

zend_hash_init(myht, 0, NULL, ZVAL_PTR_DTOR, 0);
MAKE_STD_ZVAL(zv);
ZVAL_STRING(zv, "foo", 1);

/* In PHP: $array[42] = "foo" */
zend_hash_index_update(myht, 42, &zv, sizeof(zval *), NULL);

zend_hash_destroy(myht);

/* Same as efree(myht); */
FREE_HASHTABLE(myht);

HashTable *names, *options = NULL;
HashPosition pos;//此值是Bucket的指针,pos->h表示的即是当前值的index
zval **val;
zend_bool key_exist;

//基于string key的操作函数

key_exist = zend_hash_exists(options, "key", sizeof("key"));
//在hashtable中查找key,如果查到则返回true,只针对于"key" => "value"这样的数组
zend_hash_find(options, "hello", sizeof("hello"), (void **)&val) == SUCCESS; 
//在options中查找hello,如果找到则返回SUCCESS

char *k1 = "key1";
zval *v1;
MAKE_STD_ZVAL(v1);
ZVAL_STRING(v1, "value1", 1);
zend_hash_add(names, k1, sizeof(k1), &v1, sizeof(zval *), NULL); //为添加hashtable添加一个新的元素, 即 "key1" => "value1"

zend_hash_update(names, "name", sizeof("name"), &v2, sizeof(zval *), NULL);//按key更新hashtable元素的值

zend_hash_del(names, k1, sizeof(k1));//按key删除一个元素

//基于long key的操作函数

zval *v3;
MAKE_STD_ZVAL(v3);
ZVAL_STRING(v3, "value3", 1);
zend_hash_index_update(names, 0, &v3, sizeof(zval *), NULL);//按数字索引键更新HashTable元素的值

zval **v4;
zend_hash_index_find(names, 1, &v4); //按数字索引获取HashTable元素的值
php_printf("v4 : ");
PHPWRITE(Z_STRVAL_PP(v4), Z_STRLEN_PP(v4));
php_printf("\n");

ulong idx;
idx = zend_hash_index_exists(names, 10);//按数字索引查找HashTable,如果找到返回 1, 反之则返回 0

zend_hash_index_del(names, 2);    //按数字索引删除HashTable元素

//hashTable的遍历函数

zend_hash_internal_pointer_reset(names); //初始化hash指针
zend_hash_internal_pointer_reset_ex(names, &pos);//初始化hash指针,并付值给pos

zend_hash_get_current_data(names, (void**) &val); //获取当前hash存储值,data should be cast to void**, ie: (void**) &data
zend_hash_get_current_data_ex(names, (void**) &val, &pos) == SUCCESS; //获取当前hash存储值

zend_hash_get_current_key(names, &key, &klen, &index, 0) == HASH_KEY_IS_LONG
zend_hash_get_current_key_ex(names, &key, &klen, &index, 0, &pos) == HASH_KEY_IS_LONG; //读取hashtable当前的KEY,返回值会有两种 HASH_KEY_IS_LONG | HASH_KEY_IS_STRING ,分别对应array("value"),array("key"=>"value")两种hashtable

zend_hash_move_forward(names); 
zend_hash_move_forward_ex(names, &pos); //hash指针移至下一位

//HashTable长度
php_printf("%*carray(%d) {\n", depth * 2, ' ', zend_hash_num_elements(Z_ARRVAL_P(zv))

3,数组函数说明

1)Zend's API for Associative Arrays
zval *arr;
MAKE_STD_ZVAL(arr);

array_init(arr); //$arr = array();
add_assoc_long(arr, "a", 10); //$arr["a"] = 10; 
add_asoc_unset(arr, "a"); //unset(arr["a"]);
add_assoc_bool(arr, "b", 1); //$arr["b"] = true;
add_assoc_resource(arr, "c", 10); //$arr["c"] = $resource;
add_assoc_double(arr, "d", 2.15); //$arr["d"] = 2.15;
add_assoc_string(arr, "e", "hello", 1); //$arr["e"] = "hello";最后一个参数表示字符串值是否复制
add_assoc_stringl();

zval *sub;
MAKE_STD_ZVAL(sub);
array_init(sub);
add_assoc_zval(arr, "f", sub); //$arr["f"] = $sub;
2)Zend's API for Indexed Arrays, Part 1
zval *arr;
MAKE_STD_ZVAL(arr);

array_init(arr); //$arr = array();
add_index_long(arr, 1, 10); //$arr[1] = 10;
add_index_unset(arr, 1); //unset($arr[1]);
add_index_bool(arr, 2, 1); //$arr[2] = true;
add_index_resource(arr, 3, 10); //$arr[3] = $resource;
add_index_double(arr, 4, 2.15); //$arr[4] = 2.15;
add_index_string(arr, 5, "hello", 1); //$arr[5] = "hello";最后一个参数表示字符串值是否复制
add_index_stringl();

zval *sub;
MAKE_STD_ZVAL(sub);
array_init(sub);
add_index_zval(arr, 6, sub); //$arr[6] = $sub;
3)Zend's API for Indexed Arrays, Part 2
zval *arr;
MAKE_STD_ZVAL(arr);

array_init(arr); //$arr = array();
add_next_index_long(arr, 10); //$arr[] = 10;
add_next_index_unset(arr); //unset($arr[]);
add_next_index_bool(arr, 1); //$arr[] = true;
add_next_index_resource(arr, 10); //$arr[] = $resource;
add_next_index_double(arr, 2.15); //$arr[] = 2.15;
add_next_index_string(arr, "hello", 1); //$arr[] = "hello";最后一个参数表示字符串值是否复制
add_next_index_stringl();

zval *sub;
MAKE_STD_ZVAL(sub);
array_init(sub);
add_next_index_zval(arr, sub); //$arr[] = $sub;