標籤:des style blog http io color ar os 使用
1.變數操作 設定變數 ZVAL_*系列函數; 例: zval t; ZVAL_STRING(t,"10",2); 擷取變數 Z_* 系列函數 擷取變數指標 Z_*_P 系列函數 擷取變數指標的指標 Z_*_PP 系列函數 例: Z_STRVAL(t); Z_STRLEN(t); 變數類型轉換 convert_to_* 系列函數 例: convert_to_long_ex(t); 擷取變數類型 Z_TYPE Z_TYPE_P Z_TYPE_PP 可以同 IS_* 系列常量對比 例: if(Z_TYPE_P(filehandle)!=IS_LONG) php_printf("this is long type!"); 申請變數的記憶體 一般 ALLOC_ZVAL(zv) ,MAKE_STD_ZVAL(zv)宏,用完釋放 FREE_ZVAL(zv)等宏 釋放變數記憶體 zval_dtor(zval) zval_ptr_dtor(&zval); FREE_ZVAL(zval); 注意:FREE_ZVAL 只釋放zval結構體記憶體,而zval_dtor會釋放zval變數及value指標記憶體 列印變數 php_printf("hi function!"); 返回輸出資料流,可以使用 php_write() 繼續寫 字串變數產生函數 spprintf(char **pbuf, size_t max_len, const char *format, ...); 用完釋放efree(); 申請記憶體並複製字串的副本 estrdup(&a) estrndup(&a,10); 變數記憶體申請:emalloc(size) efree(ptr) 不要用malloc 除非你能明確釋放掉 2.全域變數輔助宏: EG(v);//全域變數 executor_globals 如$_GLOBALS[EG(symbol_table),地址:EG(active_symbol_table) PG(v);//核心變數 php_core_globals 如:$_GET $_POST .. PG(http_globals)[TRACK_VARS_*],INI資訊 SG(v);//SAPI變數 請求資料 sapi_globals_struct 如:HTTP原始請求變數 sapi_request_info CG(v);//編譯變數 compiler_globals 可以得到函數表,類表 EX(v);//當前執行資料 zend_execute_data 可以擷取到當前執行的函數,類,OPCODE等 OG(v);//輸出變數 output_globals 3.函數,分5類 ZEND_*_FUNCTION 以下為C定義內建函數 函數參數說明 FOR C: int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used ht 參數個數,但不能直接使用,該用 ZEND_NUM_ARGS()擷取 return_value 函數返回zval return_value_ptr 傳回值的指標,但想控制傳回值的內容,不是直接返回傳回值時候用到,如參數引用實現. this_ptr 如果當前方法是一個對象的方法,此值指向該方法指向的對象,不能直接使用,使用 getThis() 函數 return_value_used 傳回值有沒有被使用 例: int argc = ZEND_NUM_ARGS(); char *str=NULL; int strlen; //注意:字串參數為指標的指標 長度為整形的指標 if (zend_parse_parameters(argc TSRMLS_CC, "s|s",&str,&strlen) ==FAILURE) { return; } 關於返回 修改 return_value_ptr 指標指向要用ALLOC_ZVAL_*宏申請記憶體, 參考:http://www.walu.cc/phpbook/6.1.md 返回的宏 RETURN_*系列函數,資源用 ZEND_REGISTER_RESOURCE RETURN_ZVAL(); 返回zval結構 如果是申請的記憶體,RETURN_ZVAL(zv, copy, dtor) copy 0 dtor 0 如果是堆棧記憶體 RETURN_ZVAL(zv, copy, dtor) copy 1 dtor 04.數組與HASH表 1. zvalue_value 是個union 數組時為 hashtable 2. hashtable 表有很對對應的處理函數:zend_hash_*系列函數 3. 數組上的HASHTABLE一般不直接操作,通過add_*系列函數處理 4. hashtable 記憶體申請 ALLOC_HASHTABLE 等宏處理,用完釋放FREE_HASHTABLE 5. 數組初始化也不要用直接處理hashtable,使用 array_init 處理5.資源變數 1. 需要使用資源變數須先得到一個資源清單 參數:1.請求資源,每次請求會清空此請求的資源清單 2.永久資源,服務啟動後永久儲存 3.顯示資源名 4.內部管理參數,忽略 le_myfile = zend_register_list_destructors_ex(myfile_dtor,NULL,"standard-c-file", module_number); static void myfile_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC){ FILE *fp = (FILE *) rsrc->ptr;//轉換指定類型,方便以後操作 fclose(fp); } 2. 把資源註冊進資源清單,並設定return_value int r=ZEND_REGISTER_RESOURCE(return_value, fp, le_myfile); 3. 查詢資源 filehandle 為資源zval ZEND_FETCH_RESOURCE(fp, FILE *, &filehandle, -1, "standard-c-file",le_myfile); if (fp == NULL){ RETURN_FALSE; } 4.刪除資源 filehandle 為資源zval if (zend_list_delete(Z_RESVAL_P(filehandle)) == FAILURE) { RETURN_FALSE; } 5.全域函數 zend_function_entry test_functions[] = { //參數 : 函數名 ZEND_FE(myecho, NULL) {NULL, NULL, NULL} }; 註冊到模組中 zend_module_entry php_test_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif "my test ext",//模組名 test_functions,//函數列表 NULL, NULL, NULL, NULL, PHP_MINFO(php_test),//模組介紹 #if ZEND_MODULE_API_NO >= 20010901 "1.6.0", //版本 #endif STANDARD_MODULE_PROPERTIES }; //函數實現,參考 3.函數部分 PHP_FUNCTION(myecho){} 使用者函數調用: 參數: function_table 函數表,全域從&CG(function_table)得到 對象,如果該函數是對象的方法,沒有傳NULL 函數名 傳回值儲存 zval指標, 參數數量 參數數組 call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, zend_uint param_count, zval *params[] TSRMLS_DC); 6.類的實現,結構:zend_class_entry 分兩種 ZEND_INTERNAL_CLASS 和 ZEND_USER_CLASS //存取權限控制:ZEND_ACC_*系列宏 //類方法定義 //參數:類名 方法名 ZEND_METHOD( myclass , public_method ) { php_printf("hi function!"); } //註冊到函數列表 static zend_function_entry myclass_method[]={ //參數:類名 方法名 靜態方法加 ZEND_ACC_STATIC ZEND_ME(myclass, public_method, NULL, ZEND_ACC_PUBLIC) {NULL,NULL,NULL} }; zend_class_entry ce; zend_class_entry *myclass_ce; //參數:初始結構 類名 方法列表 INIT_CLASS_ENTRY(ce,"myclass",myclass_method); //此方法會根據ce拷貝產生一個zend_class_entry並掛載到類列表中 zend_register_internal_class(&ce TSRMLS_CC); //添加類的屬性 //參數:類指標 屬性名稱 屬性名稱長度 屬性存取權限 : zend_declare_property_* 系列函數 zend_declare_property_null(myclass_ce, "public_var", strlen("public_var"), ZEND_ACC_PUBLIC TSRMLS_CC); //定義類常量: //參數:類指標 屬性名稱 屬性名稱長度 屬性存取權限 : zend_declare_class_constant* 系列函數 zend_declare_class_constant_null(myclass_ce, "aaa", 3 TSRMLS_DC); 讀取類靜態屬性 ZEND_API zval *zend_read_static_property( zend_class_entry *scope, char *name, int name_length, //屬性不存在是否拋出 notice zend_bool silent TSRMLS_DC ); 更新類靜態屬性 ZEND_API int zend_update_static_property( zend_class_entry *scope, char *name, int name_length, zval *value TSRMLS_DC ); 其他封裝的快捷函數 zend_update_static_property_* 7.介面 結構也是: zend_class_entry static zend_function_entry i_myinterface_method[]={ //注意這裡的null指的是arg_info,具體可以參考:參數 arg_info 的定義 ZEND_ABSTRACT_ME(i_myinterface, hello, NULL) {NULL,NULL,NULL} }; //定義及初始化 zend_class_entry ce; INIT_CLASS_ENTRY(ce, "i_myinterface", i_myinterface_method); i_myinterface_ce = zend_register_internal_interface(&ce TSRMLS_CC);8.繼承及介面實現 1.實現介面: 寫完類,介面後添加: 參數: 類指標 ,實現介面數量,介面指標... zend_class_implements(class_ce TSRMLS_CC,1,myinterface_ce); 2.實現繼承: 註冊類時候使用: zend_register_internal_class_ex 參數: 類指標 父類指標 父類名 myclass_ce = zend_register_internal_class_ex(&ce,parent_class_ce,"parent_class" TSRMLS_CC);8.對象 zend_object_value 結構: typedef struct _zend_object_value { //unsigned int類型,EG(objects_store).object_buckets的索引 zend_object_handle handle; zend_object_handlers *handlers; } zend_object_value; 建立對象: zval *obj; MAKE_STD_ZVAL(obj); object_init_ex(obj, zend_class_entry 類名 ); //object_init(obj) Null 物件 讀取屬性: ZEND_API zval *zend_read_property( zend_class_entry *scope, zval *object, char *name, int name_length, //屬性不存在是否拋出 notice zend_bool silent TSRMLS_DC ); 更新屬性: ZEND_API int zend_update_static_property( zend_class_entry *scope, char *name, int name_length, zval *value TSRMLS_DC ); 其他封裝的快捷函數 zend_update_property_* 調用方法: ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC); zend_call_method_with_0_params(obj, obj_ce, fn_proxy, function_name, retval) zend_call_method_with_1_params(&this_zval,myclass_ce,NULL,"hello",NULL);9.常用結構及宏解釋: PHP_FN(name) 函數名產生 PHP_MN(name) 方法名產生 ZEND_NAMED_FUNCTION(name) 產生指定名的函數 一般用 PHP_FUNCTION(name) 函式宣告 ZEND_METHOD(classname, name) 類方法聲明 zend_function_entry 數組用於聲明模組或類的成員函數情況 產生zend_function_entry的元素配套宏: //註冊全域的函數 //參數:函數名 參數 PHP_FE(name, arg_info) //註冊類的函數 //參數:類名 方法名 參數 存取權限控制 PHP_ME(classname, name, arg_info, flags) //註冊類的抽象函數,類和介面都用這個 //參數:類名 方法名 參數 PHP_ABSTRACT_ME(classname, name, arg_info) 10.參數 arg_info 的定義 一般情況下不需要定義參數,除非你希望PHP般你檢查參數正確性,比如介面方法 產生arg_info的宏,以arg_say_hello為例: //參數:zend_arg_info 名,參數至少前N個 ZEND_BEGIN_ARG_INFO(arg_say_hello, 0) //參數:是否設定為引用,參數名 //ZEND_ARG_* 系列函數還可以聲明對象等 ZEND_ARG_INFO(0, name) ZEND_END_ARG_INFO() //其他介紹 //name 參數名稱 //name_len 參數名稱字串長度 //class_name 當參數類型為類時,指定類名稱 //class_name_len 類名稱字串長度 //array_type_hint 標識參數類型是否為數組 //allow_null 是否允許設定為空白 //pass_by_ref 是否設定為引用,即使用&操作符 //return_reference 標識函數將重寫return_value_ptr,後面介紹函數傳回值時再做介紹 //required_num_args 設定函數被調用時,傳遞參數至少為前N個,當設定為-1時,必須傳遞所有參數
PHP 擴充開發小結