亚洲韩日午夜视频,欧美日韩在线精品一区二区三区,韩国超清无码一区二区三区,亚洲国产成人影院播放,久草新在线,在线看片AV色

您好,歡迎來到思海網絡,我們將竭誠為您提供優質的服務! 誠征網絡推廣 | 網站備案 | 幫助中心 | 軟件下載 | 購買流程 | 付款方式 | 聯系我們 [ 會員登錄/注冊 ]
促銷推廣
客服中心
業務咨詢
有事點擊這里…  531199185
有事點擊這里…  61352289
點擊這里給我發消息  81721488
有事點擊這里…  376585780
有事點擊這里…  872642803
有事點擊這里…  459248018
有事點擊這里…  61352288
有事點擊這里…  380791050
技術支持
有事點擊這里…  714236853
有事點擊這里…  719304487
有事點擊這里…  1208894568
有事點擊這里…  61352289
在線客服
有事點擊這里…  531199185
有事點擊這里…  61352288
有事點擊這里…  983054746
有事點擊這里…  893984210
當前位置:首頁 >> 技術文章 >> 文章瀏覽
技術文章

數組在PHP內核中的實現

添加時間:2014-9-23 16:53:13  添加: 思海網絡 

PHP中經常使用數組,PHP的數組強大,而且速度也快,讀寫都可以在O(1)內完成,因為它每個元素的大小都是一致的,只要知道下標,便可以瞬間計算出其對應的元素在內存中的位置,從而直接取出或者寫入。那么內核中數組是如何實現的呢?

PHP大部分功能,都是通過HashTable來實現,其中就包括數組。

HashTable即具有雙向鏈表的優點,同時具有能與數據匹敵的操作性能。

  • PHP中的定義的變量保存在一個符號表里,而這個符號表其實就是一個HashTable,它的每一個元素都是一個zval*類型的變量。不僅如此,保存用戶定義的函數、類、資源等的容器都是以HashTable的形式在內核中實現的。

    下面分別來看在PHP、內核中如何定義數組。

    數組定義的實現

    PHP中定義數組:


    在內核中使用宏來實現:
    zval* array;
    array_init(array);
    add_assoc_string(array, "key", "value", 1);

    將上述代碼中的宏展開:
    zval* array;
    ALLOC_INIT_ZVAL(array);
    Z_TYPE_P(array) = IS_ARRAY;
    
    HashTable *h;
    ALLOC_HASHTABLE(h);
    Z_ARRVAL_P(array)=h;
    zend_hash_init(h, 50, NULL,ZVAL_PTR_DTOR, 0);
    
    zval* barZval;
    MAKE_STD_ZVAL(barZval);
    ZVAL_STRING(barZval, "value", 0);
    zend_hash_add(h, "key", 4, &barZval, sizeof(zval*), NULL);

    便捷的數組宏操作


    內核為我們提供了方便的宏來管理數組。

    //add_assoc_*系列函數:
    add_assoc_null(zval *aval, char *key);
    add_assoc_bool(zval *aval, char *key, zend_bool bval);
    add_assoc_long(zval *aval, char *key, long lval);
    add_assoc_double(zval *aval, char *key, double dval);
    add_assoc_string(zval *aval, char *key, char *strval, int dup);
    add_assoc_stringl(zval *aval, char *key,char *strval, uint strlen, int dup);
    add_assoc_zval(zval *aval, char *key, zval *value);
    
    //備注:其實這些函數都是宏,都是對add_assoc_*_ex函數的封裝。
    
    //add_index_*系列函數:
    ZEND_API int add_index_long		(zval *arg, ulong idx, long n);
    ZEND_API int add_index_null		(zval *arg, ulong idx			);
    ZEND_API int add_index_bool		(zval *arg, ulong idx, int b	);
    ZEND_API int add_index_resource	(zval *arg, ulong idx, int r	);
    ZEND_API int add_index_double	(zval *arg, ulong idx, double d);
    ZEND_API int add_index_string	(zval *arg, ulong idx, const char *str, int duplicate);
    ZEND_API int add_index_stringl	(zval *arg, ulong idx, const char *str, uint length, int duplicate);
    ZEND_API int add_index_zval		(zval *arg, ulong index, zval *value);
    
    //add_next_index_*函數:
    ZEND_API int add_next_index_long		(zval *arg, long n	);
    ZEND_API int add_next_index_null		(zval *arg			);
    ZEND_API int add_next_index_bool		(zval *arg, int b	);
    ZEND_API int add_next_index_resource	(zval *arg, int r	);
    ZEND_API int add_next_index_double		(zval *arg, double d);
    ZEND_API int add_next_index_string		(zval *arg, const char *str, int duplicate);
    ZEND_API int add_next_index_stringl		(zval *arg, const char *str, uint length, int duplicate);
    ZEND_API int add_next_index_zval		(zval *arg, zval *value);

    下面可以對比一下數組常見操作所對應的宏。

    add_next_index_*()

    PHP中				內核中
    $arr[] = NULL;		add_next_index_null(arr);
    $arr[] = 42;		add_next_index_long(arr, 42);
    $arr[] = true;		add_next_index_bool(arr, 1);
    $arr[] = 3.14;		add_next_index_double(arr, 3.14);
    $arr[] = 'foo';		add_next_index_string(arr, "foo");
    $arr[] = $var;		add_next_index_zval(arr, zval);

    add_index_*()
    PHP中				內核中
    $arr[0] = NULL;		add_index_null(arr, 0);
    $arr[1] = 42;		add_index_long(arr, 1, 42);
    $arr[2] = true;		add_index_bool(arr, 2, 1);
    $arr[3] = 3.14;		add_index_double(arr, 3, 3.14);
    $arr[4] = 'foo';	add_index_string(arr, 4, "foo", 1);
    $arr[5] = $var;		add_index_zval(arr, 5, zval);

    add_assoc_*()
    PHP中					內核中
    $arr["abc"] = NULL;		add_assoc_null(arr, "abc");
    $arr["def"] = 42;		add_assoc_long(arr, "def", 42);
    $arr["ghi"] = true;		add_assoc_bool(arr, "ghi", 1);
    $arr["jkl"]  = 3.14		add_assoc_double(arr, "jkl", 3.14);
    $arr["mno"]="foo"		add_assoc_string(arr, "mno", "foo", 1");
    $arr["pqr"] = $var;		add_assoc_zval(arr, "pqr", zval);

    一個完整的實例

    下面在PHP中定義一個函數,并在其中使用數組。然后來看在內核中如何實現。


    內核中實現:
    PHP_FUNCTION(array_test){
    	char* mystr;
    	zval* mysubarray;
    
    	array_init(return_value);
    
    	add_index_long(return_value, 42, 123);
    
    	add_next_index_string(return_value, "test", 1);
    
    	add_next_index_stringl(return_value, "test_stringl", 10, 1);
    
    	mystr = estrdup("Forty Five");
    
    	add_next_index_string(return_value, mystr, 0);
    
    	add_assoc_double(return_value, "double", 3.14);
    
    	ALLOC_INIT_ZVAL(mysubarray);
    	array_init(mysubarray);
    	add_next_index_string(mysubarray, "hello", 1);
    	add_assoc_zval(return_value, "subarray", mysubarray);
    }

    你可能會疑問上面代碼中的變量return_value在哪里定義的。下面將PHP_FUNCTION展開,你就明白了。
    zif_array_test(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC);

    沒錯,實際上每個函數都有一個默認的返回值return_value。在使用RETVAL_*()、RETURN_*()作為函數返回值時,僅僅是修改return_value。
  • 關鍵字:PHP、內核、數據
分享到:

頂部 】 【 關閉
版權所有:佛山思海電腦網絡有限公司 ©1998-2024 All Rights Reserved.
聯系電話:(0757)22630313、22633833
中華人民共和國增值電信業務經營許可證: 粵B1.B2-20030321 備案號:粵B2-20030321-1
網站公安備案編號:44060602000007 交互式欄目專項備案編號:200303DD003  
察察 工商 網安 舉報有獎  警警  手機打開網站