PHP擴充套件開發(6) 接收引數

2021-06-18 09:00:59 字數 3446 閱讀 9113

函式的引數則是php**層和c**層之間交換資料的唯一途徑,因為php的呼叫語法是動態的,不會做任何錯誤檢查,所以檢查引數工作需要交給開發php擴充套件人員完成,看一下我們在快速入門裡面的一段**,使用zend_parse_parameters來解析引數:

php_function(say_goodbye)

len = spprintf(&strg, 0, "goodbye %s\n", arg);

return_stringl(strg, len, 0);

}

獲取引數數量

php無法根據函式的顯式宣告來對呼叫進行語法檢查,而且它還支援可變引數,所以我們就不得不在所呼叫函式的內部來獲取引數個數。我們可以使用巨集zend_num_args來獲取引數個數,如下面的**:

if(zend_num_args() != 2)

這段**使用巨集wrong_param_count丟擲乙個引數個數錯誤。

開發php擴充套件時,解析引數基本是使用標準方式zend_parse_parameters,使用方式如下所示:

int zend_parse_parameters(int num_args tsrmls_dc, char *type_spec, ...);

num_args引數指定引數個數,前面介紹過使用zend_num_args獲取引數個數;tsrmls_dc巨集指定執行緒安 全;type_spec引數是乙個字串,指定各個引數的型別,每個引數型別用乙個字母表示。如果成功地解析和接收到了引數並且在轉換期間也沒出現錯誤, 那麼這個函式就會返回success,否則返回failure,各個引數型別的字母標識如下:

l - 長整數 

d - 雙精度浮點數 

s - 字串 (也可能是空位元組)和其長度 

b - 布林值 

r - 資源, 儲存在 zval* 

a - 陣列, 儲存在 zval* 

o - (任何類的)物件, 儲存在 zval* 

o - (由class entry 指定的類的)物件, 儲存在 zval* 

z - 實際的 zval*

在設定引數型別時,還可以使用以下幾個特殊的字元:

| - 表明剩下的引數都是可選引數。如果使用者沒有傳進來這些引數值,那麼這些值就會被初始化成預設值。 

/ - 表明引數解析函式將會對剩下的引數以 separate_zval_if_not_ref() 的方式來提供這個引數的乙份拷貝,除非這些引數是乙個引用。 

! - 表明剩下的引數允許被設定為 null(僅用在 a、o、o、r和z身上)。如果使用者傳進來了乙個 null 值,則儲存該引數的變數將會設定為 null。

看看官方文件中提供的幾個例子:

/* 取得乙個長整數,乙個字串和它的長度,再取得乙個 zval 值。 */

long l;

char *s;

int s_len;

zval *param;

if (zend_parse_parameters(zend_num_args() tsrmls_cc, "lsz", &l, &s, &s_len, ¶m) == failure)

/* 取得乙個由 my_ce 所指定的類的乙個物件,另外再取得乙個可選的雙精度的浮點數。 */

zval *obj;

double d = 0.5;

if (zend_parse_parameters(zend_num_args() tsrmls_cc, "o|d", &obj, my_ce, &d) == failure)

/* 取得乙個物件或空值,再取得乙個陣列。如果傳遞進來乙個空物件,則 obj 將被設定為 null。*/

zval *obj;

zval *arr;

if (zend_parse_parameters(zend_num_args() tsrmls_cc, "o!a", &obj, &arr) == failure)

/* 取得乙個分離過的陣列。*/

zval *arr;

if (zend_parse_parameters(zend_num_args() tsrmls_cc, "a/", &arr) == failure)

/* 僅取得前 3 個引數(這對可變引數的函式很有用)。*/

zval *z;

zend_bool b;

zval *r;

if (zend_parse_parameters(3, "zbr!", &z, &b, &r) == failure)

在接收引數時還有乙個可用的函式zend_parse_parameters_ex,允許我們傳入一些flags來控制解析引數的動作,使用方式如下所示:

int zend_parse_parameters_ex(int flags, int num_args tsrmls_dc, char *type_spec, ...);

目前flags僅能傳入zend_parse_params_quiet這個值,表示函式不輸出任何錯誤資訊,如下面的示例:

long l1, l2, l3;

char *s;

if (zend_parse_parameters_ex(zend_parse_params_quiet,

zend_num_args() tsrmls_cc,

"lll", &l1, &l2, &l3) == success) else if (zend_parse_parameters_ex(zend_parse_params_quiet,

zend_num_args(), "s", &s, &s_len) == success) else

由於php支援可變引數,所以在接收可變引數時,使用前面介紹的兩個方法就不太合適,我們可以用zend_get_parameters_array_ex()來代替,如下面的示例:

zval **parameter_array[4];

/* 取得引數個數 */

argument_count = zend_num_args();

/* 看一下引數個數是否滿足我們的要求:最少 2 個,最多 4個。 */

if(argument_count < 2 || argument_count > 4)

/* 引數個數正確,開始接收。 */

if(zend_get_parameters_array_ex(argument_count, parameter_array) != success)

本文我們介紹了在php擴充套件中接收引數,總共有三個函式:zend_parse_parameters、zend_parse_parameters_ex、zend_get_parameters_array_ex,關於引數解析其實還有更複雜的內容,下篇再介紹。

[**] 

php擴充套件開發

php擴充套件 pecl 跟php引擎一樣都是使用c語言開發。php核心開發組成員鳥哥laruence使用的是vim進行php開發。書籍 案例 php src ext pecl開發郵件組 盡量編寫一些phpt測試用例,php src tests下有很多參考.測試時用 enable debug編譯ph...

php擴充套件開發

二 php擴充套件開發 擴充套件開發流程 生成開發骨架 修改config.m4 編碼 編譯擴充套件為so 修改php.ini 1.生成開發骨架 1.1 進入擴充套件目錄 cd php 7.0.1 ext 1.2 用.ext skel生成骨架 ext skel extname module 1.3 修...

PHP擴充套件開發

php function say hello len spprintf strg,0,hello s n arg return stringl strg,len,0 1.引數接收 這裡接收函式的引數需要通過zend parse parameter函式解析,第乙個引數指定使用者傳入say hello函...