天天看點

PHP擴充開發-05-參數接收1      參數接收

1      參數接收

前面我們講到了php擴充開發的大體架構,本節我們介紹擴充如何接收php腳本中傳入的參數。

1.1     普通參數接收

任務:寫一個擴充,輸出php腳本傳入的參數。例如php –r “echo hello(‘param test.’);” 将要輸出param test.

首先我們建立一個paramtest的擴充,建議、編譯、安裝、測試過程不再贅述。

首先,我們需要建立一個函數叫做hello,建立的過程和之前是一樣的,也不多說。

我們具體看一下,hello函數的實作,paramtest.c中hello函數的實作如下:

PHP_FUNCTION(hello)

{

    char* str_hello;

    int int_hello_str_length;

if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"s",

&str_hello,&int_hello_str_length)== FAILURE)

    {  

        RETURN_NULL();

    }  

    php_printf("%s", str_hello);

    RETURN_TRUE;

}

我們先看一下zend_parse_parameters的函數定義:ZEND_NUM_ARGS() TSRMLS_CC其實是zend_parse_parameters的兩個參數,具體可以查找這兩個宏的定義,這兩個宏主要是傳入參數資訊和保證線程安全。參數”s”其實是格式化字元串,也就是說這個參數告訴ZEND編譯器,我可以接收的參數類型是什麼樣子的。Zend_parse_parameters的其他參數負責具體接收php腳本中函數變量的值。

請注意:我們在php腳本的函數中傳入了一個參數,但是在zend_parse_parameters中卻需要兩個參數進行接收,給大家解釋一下原因:我們在php腳本中傳入的參數是字元串,對于C語言來說,PHP腳本傳入字元串的長度是無法直接用函數strlen來進行擷取的。原因是因為,我們在php腳本中可以傳入\0,但是\0在C語言中是字元串結尾的意思。

在zend_parse_parameters中,格式化字元創(本例中是”s”)有很多,如果你想要接受多個參數的話,隻要在格式化參數中加入相應的類型标示符,在參數中添加接受變量就可以了。例如,如果你的php函數需要傳入兩個變量,第一個變量為問候字元串,第二個參數為bool,表示是否輸出,那麼zend_parse_parameters函數可以這樣寫:zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sb", &str_hello,&len, &is_output)。

其中,格式化字元串可以清單如下:

PHP變量類型 代碼 C擴充變量類型
boolean b zend_bool
long l long
double d double
string s char*, int
resource r zval*
array a zval*
object o zval*
zval z zval*

            上表中有很多zval類型,這個類型我們下一節進行單獨介紹。

另外一個需要注意的地方是,我們使用php_printf在C函數中進行輸出,你能想到原因嗎?前面我們已經講到php既可以作為腳本在指令行運作,也可以通過web伺服器,以單程序、多程序、多線程方式運作,如果我們在web伺服器中将我們的資訊輸出到stdout中,會導緻資訊無法輸出或者輸出錯誤。給大家舉個例子,我們可以再apache+php環境中寫一個腳本,通過浏覽器通路這個腳本,如果你使用printf輸出字元串,那麼浏覽器将無法看到你的輸出資訊。但是如果你使用php_printf輸出的話,浏覽器就能顯示你輸出的資訊。

1.2     可選參數接收

我們已經學會了如何接收普通參數,大家都知道php中還有可選參數,那麼我們改怎樣接收可選參數呢?(如果你不知道php可以使用可選參數的話,建議你先溫習一下php的基礎知識。)

         這個很簡單,我們直接上代碼:

PHP_FUNCTION(hello)

{

    char* str_hello;

    int int_hello_str_length;

    zend_bool is_output =0;

if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"s|b",&str_hello,

&int_hello_str_length,&is_output)== FAILURE)

    {  

        RETURN_NULL();

    }  

    if(is_output)

    {  

        php_printf("%s", str_hello);

    }  

    RETURN_TRUE;

}

很簡單吧,如果你有可選參數,那麼在格式化字元串中加入|就可以了,|後面的就是可選參數,其他的和普通變量的接收是一樣的。

author iamnew<[email protected]>

QQ:947847775