PHP7擴展開發(fā)之傳參與返回值

前言

這次,我們將演示如何在PHP擴展中接受傳入的參數(shù)和輸出返回值。

<?php
    function default_value ($type, $value = null) {
        if ($type == "int") {
            return $value ?? 0;
        } else if ($type == "bool") {
            return $value ?? false;
        } else if ($type == "str") {
            return is_null($value) ? "" : $value;
        }
        return null;
    }

    var_dump(default_value("int"));
    var_dump(default_value("int", 1));
    var_dump(default_value("bool"));
    var_dump(default_value("bool", true));
    var_dump(default_value("str"));
    var_dump(default_value("str", "a"));
    var_dump(default_value("array"));
?>

我們將在擴展中實現(xiàn)default_value方法挺物。

代碼

基礎(chǔ)代碼

這個擴展椰棘,我們將在say擴展上增加 default_value 方法纺棺。say擴展相關(guān)代碼大家請看這篇博文。PHP7擴展開發(fā)之hello word 文中已經(jīng)詳細(xì)介紹了如何創(chuàng)建一個擴展和提供了源碼下載邪狞。

實現(xiàn)default_value方法

str_concat方法的PHP擴展源碼:

PHP_FUNCTION(default_value)
{
    zend_string     *type;    
    zval            *value = NULL;

#ifndef FAST_ZPP
    /* Get function parameters and do error-checking. */
    if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|z", &type, &value) == FAILURE) {
        return;
    }    
#else
    ZEND_PARSE_PARAMETERS_START(1, 2)
        Z_PARAM_STR(type)
        Z_PARAM_OPTIONAL
        Z_PARAM_ZVAL_EX(value, 0, 1)
    ZEND_PARSE_PARAMETERS_END();
#endif
    
    if (ZSTR_LEN(type) == 3 && strncmp(ZSTR_VAL(type), "int", 3) == 0 && value == NULL) {
        RETURN_LONG(0);
    } else if (ZSTR_LEN(type) == 3 && strncmp(ZSTR_VAL(type), "int", 3) == 0 && value != NULL) {
        RETURN_ZVAL(value, 0, 1); 
    } else if (ZSTR_LEN(type) == 4 && strncmp(ZSTR_VAL(type), "bool", 4) == 0 && value == NULL) {
        RETURN_FALSE;
    } else if (ZSTR_LEN(type) == 4 && strncmp(ZSTR_VAL(type), "bool", 4) == 0 && value != NULL) {
        RETURN_ZVAL(value, 0, 1); 
    } else if (ZSTR_LEN(type) == 3 && strncmp(ZSTR_VAL(type), "str", 3) == 0 && value == NULL) {
        RETURN_EMPTY_STRING();
    } else if (ZSTR_LEN(type) == 3 && strncmp(ZSTR_VAL(type), "str", 3) == 0 && value != NULL) {
        RETURN_ZVAL(value, 0, 1); 
    } 
    RETURN_NULL();
}

代碼解讀

獲取參數(shù)

在PHP7中提供了兩種獲取參數(shù)的方法祷蝌。zend_parse_parameters和FAST ZPP方式。

zend_parse_parameters

在PHP7之前一直使用zend_parse_parameters函數(shù)獲取參數(shù)帆卓。這個函數(shù)的作用巨朦,就是把傳入的參數(shù)轉(zhuǎn)換為PHP內(nèi)核中相應(yīng)的類型,方便在PHP擴展中使用剑令。
參數(shù)說明:
第一個參數(shù)糊啡,參數(shù)個數(shù)。一般就使用ZEND_NUM_ARGS()吁津,不需要改變棚蓄。
第二個參數(shù),格式化字符串碍脏。這個格式化字符串的作用就是梭依,指定傳入?yún)?shù)與PHP內(nèi)核類型的轉(zhuǎn)換關(guān)系。

代碼中 S|z 的含義就是:
S 表示參數(shù)是一個字符串典尾。要把傳入的參數(shù)轉(zhuǎn)換為zend_string類型役拴。
| 表示之后的參數(shù)是可選〖毓。可以傳河闰,也可以不傳科平。
z 表示參數(shù)是多種類型。要把傳入的參數(shù)轉(zhuǎn)換為zval類型姜性。

除此之外匠抗,還有一些specifier,需要注意:
污抬!如果接收了一個PHP語言里的null變量汞贸,則直接把其轉(zhuǎn)成C語言里的NULL,而不是封裝成IS_NULL類型的zval印机。
/ 如果傳遞過來的變量與別的變量共用一個zval矢腻,而且不是引用,則進行強制分離射赛,新的zval的is_ref__gc==0, and refcount__gc==1.

更多格式化字符串的含義可以查看官方網(wǎng)站多柑。https://wiki.php.net/rfc/fast_zpp

FAST ZPP

在PHP7中新提供的方式。是為了提高參數(shù)解析的性能楣责。對應(yīng)經(jīng)常使用的方法竣灌,建議使用FAST ZPP方式。
使用方式:
ZEND_PARSE_PARAMETERS_START(1, 2)開頭秆麸。
第一個參數(shù)表示必傳的參數(shù)格式初嘹,第二個參數(shù)表示最多傳入的參數(shù)個數(shù)。
ZEND_PARSE_PARAMETERS_END();結(jié)束沮趣。
中間是傳入?yún)?shù)的解析屯烦。
值得注意的是,一般FAST ZPP的宏方法與zend_parse_parameters的specifier是一一對應(yīng)的房铭。如:
Z_PARAM_ARRAY 對應(yīng) |
Z_PARAM_STR 對應(yīng) S
但是驻龟,Z_PARAM_ZVAL_EX方法比較特殊。它對應(yīng)兩個specifier缸匪,分別是 ! 和 / 翁狐。! 對應(yīng)宏方法的第二個參數(shù)。/ 對應(yīng)宏方法的第三個參數(shù)凌蔬。如果想開啟露懒,只要設(shè)置為1即可。

FAST ZPP相應(yīng)的宏方法可以查看官方網(wǎng)站 https://wiki.php.net/rfc/fast_zpp#proposal

返回值

方法的返回值是使用RETURN_開頭的宏方法進行返回的龟梦。常用的宏方法有:
RETURN_NULL() 返回null
RETURN_LONG(l) 返回整型
RETURN_DOUBLE(d) 返回浮點型
RETURN_STR(s) 返回一個字符串隐锭。參數(shù)是一個zend_string * 指針
RETURN_STRING(s) 返回一個字符串窃躲。參數(shù)是一個char * 指針
RETURN_STRINGL(s, l) 返回一個字符串计贰。第二個參數(shù)是字符串長度。
RETURN_EMPTY_STRING() 返回一個空字符串蒂窒。
RETURN_ARR(r) 返回一個數(shù)組躁倒。參數(shù)是zend_array *指針荞怒。
RETURN_OBJ(r) 返回一個對象。參數(shù)是zend_object *指針秧秉。
RETURN_ZVAL(zv, copy, dtor) 返回任意類型褐桌。參數(shù)是 zval *指針。
RETURN_FALSE 返回false
RETURN_TRUE 返回true

更多宏方法請查看 Zend/zend_API.h中的相關(guān)代碼象迎。
更多函數(shù)說明請查看

源碼下載

tar.gz格式下載
zip格式下載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荧嵌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子砾淌,更是在濱河造成了極大的恐慌啦撮,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汪厨,死亡現(xiàn)場離奇詭異赃春,居然都是意外死亡,警方通過查閱死者的電腦和手機劫乱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門织中,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人衷戈,你說我怎么就攤上這事狭吼。” “怎么了殖妇?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵搏嗡,是天一觀的道長。 經(jīng)常有香客問我拉一,道長采盒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任蔚润,我火速辦了婚禮磅氨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嫡纠。我一直安慰自己烦租,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布除盏。 她就那樣靜靜地躺著叉橱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪者蠕。 梳的紋絲不亂的頭發(fā)上窃祝,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音踱侣,去河邊找鬼粪小。 笑死大磺,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的探膊。 我是一名探鬼主播杠愧,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼逞壁!你這毒婦竟也來了流济?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤腌闯,失蹤者是張志新(化名)和其女友劉穎袭灯,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绑嘹,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡稽荧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了工腋。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姨丈。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖擅腰,靈堂內(nèi)的尸體忽然破棺而出蟋恬,到底是詐尸還是另有隱情,我是刑警寧澤趁冈,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布歼争,位于F島的核電站,受9級特大地震影響渗勘,放射性物質(zhì)發(fā)生泄漏沐绒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一旺坠、第九天 我趴在偏房一處隱蔽的房頂上張望乔遮。 院中可真熱鬧,春花似錦取刃、人聲如沸蹋肮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坯辩。三九已至,卻和暖如春崩侠,著一層夾襖步出監(jiān)牢的瞬間漆魔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留有送,地道東北人淌喻。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓僧家,卻偏偏與公主長得像雀摘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子八拱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 本方案中采用的PHP擴展方式為: ?下載PHP對應(yīng)版本的源碼阵赠,在其中加入、生成擴展(如smsupport.so)肌稻;...
    WebSSO閱讀 1,619評論 1 2
  • 在閱讀下面的內(nèi)容之前清蚀,我假定已看到的人已經(jīng)對 PHP 7 基本的數(shù)據(jù)結(jié)構(gòu)都有大致的了解了,這是下面內(nèi)容閱讀的前提爹谭。...
    優(yōu)才學(xué)院閱讀 2,445評論 0 3
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理枷邪,服務(wù)發(fā)現(xiàn),斷路器诺凡,智...
    卡卡羅2017閱讀 134,599評論 18 139
  • 千呼萬喚始出來东揣,PHP7終于如約而來,對所有PHPer都是一件振奮人心的事腹泌。因為可能很多小伙伴很有可能正和我經(jīng)歷同...
    maquewy閱讀 1,743評論 0 4
  • 寫php擴展不僅僅只是要求會c語言嘶卧,還需要了解php源碼。 因為自己寫的東西凉袱,總會有這樣那樣的缺點芥吟,比如內(nèi)存泄...
    等哈哈咯閱讀 979評論 0 0