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

前言

這次,我們將演示如何在PHP擴(kuò)展中接受傳入的參數(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"));
?>

我們將在擴(kuò)展中實(shí)現(xiàn)default_value方法。

代碼

基礎(chǔ)代碼

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

實(shí)現(xiàn)default_value方法

str_concat方法的PHP擴(kuò)展源碼:

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ù)。這個(gè)函數(shù)的作用,就是把傳入的參數(shù)轉(zhuǎn)換為PHP內(nèi)核中相應(yīng)的類(lèi)型,方便在PHP擴(kuò)展中使用。
參數(shù)說(shuō)明:
第一個(gè)參數(shù),參數(shù)個(gè)數(shù)。一般就使用ZEND_NUM_ARGS(),不需要改變。
第二個(gè)參數(shù),格式化字符串。這個(gè)格式化字符串的作用就是,指定傳入?yún)?shù)與PHP內(nèi)核類(lèi)型的轉(zhuǎn)換關(guān)系。

代碼中 S|z 的含義就是:
S 表示參數(shù)是一個(gè)字符串。要把傳入的參數(shù)轉(zhuǎn)換為zend_string類(lèi)型。
| 表示之后的參數(shù)是可選??梢詡?,也可以不傳。
z 表示參數(shù)是多種類(lèi)型。要把傳入的參數(shù)轉(zhuǎn)換為zval類(lèi)型。

除此之外,還有一些specifier,需要注意:
!如果接收了一個(gè)PHP語(yǔ)言里的null變量,則直接把其轉(zhuǎn)成C語(yǔ)言里的NULL,而不是封裝成IS_NULL類(lèi)型的zval。
/ 如果傳遞過(guò)來(lái)的變量與別的變量共用一個(gè)zval,而且不是引用,則進(jìn)行強(qiáng)制分離,新的zval的is_ref__gc==0, and refcount__gc==1.

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

FAST ZPP

在PHP7中新提供的方式。是為了提高參數(shù)解析的性能。對(duì)應(yīng)經(jīng)常使用的方法,建議使用FAST ZPP方式。
使用方式:
ZEND_PARSE_PARAMETERS_START(1, 2)開(kāi)頭。
第一個(gè)參數(shù)表示必傳的參數(shù)格式,第二個(gè)參數(shù)表示最多傳入的參數(shù)個(gè)數(shù)。
ZEND_PARSE_PARAMETERS_END();結(jié)束。
中間是傳入?yún)?shù)的解析。
值得注意的是,一般FAST ZPP的宏方法與zend_parse_parameters的specifier是一一對(duì)應(yīng)的。如:
Z_PARAM_ARRAY 對(duì)應(yīng) |
Z_PARAM_STR 對(duì)應(yīng) S
但是,Z_PARAM_ZVAL_EX方法比較特殊。它對(duì)應(yīng)兩個(gè)specifier,分別是 ! 和 / 。! 對(duì)應(yīng)宏方法的第二個(gè)參數(shù)。/ 對(duì)應(yīng)宏方法的第三個(gè)參數(shù)。如果想開(kāi)啟,只要設(shè)置為1即可。

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

返回值

方法的返回值是使用RETURN_開(kāi)頭的宏方法進(jìn)行返回的。常用的宏方法有:
RETURN_NULL() 返回null
RETURN_LONG(l) 返回整型
RETURN_DOUBLE(d) 返回浮點(diǎn)型
RETURN_STR(s) 返回一個(gè)字符串。參數(shù)是一個(gè)zend_string * 指針
RETURN_STRING(s) 返回一個(gè)字符串。參數(shù)是一個(gè)char * 指針
RETURN_STRINGL(s, l) 返回一個(gè)字符串。第二個(gè)參數(shù)是字符串長(zhǎng)度。
RETURN_EMPTY_STRING() 返回一個(gè)空字符串。
RETURN_ARR(r) 返回一個(gè)數(shù)組。參數(shù)是zend_array *指針。
RETURN_OBJ(r) 返回一個(gè)對(duì)象。參數(shù)是zend_object *指針。
RETURN_ZVAL(zv, copy, dtor) 返回任意類(lèi)型。參數(shù)是 zval *指針。
RETURN_FALSE 返回false
RETURN_TRUE 返回true

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

源碼下載

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本方案中采用的PHP擴(kuò)展方式為: ?下載PHP對(duì)應(yīng)版本的源碼,在其中加入、生成擴(kuò)展(如smsupport.so);...
    WebSSO閱讀 1,708評(píng)論 1 1
  • 在閱讀下面的內(nèi)容之前,我假定已看到的人已經(jīng)對(duì) PHP 7 基本的數(shù)據(jù)結(jié)構(gòu)都有大致的了解了,這是下面內(nèi)容閱讀的前提。...
    優(yōu)才學(xué)院閱讀 2,991評(píng)論 0 3
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,641評(píng)論 19 139
  • 千呼萬(wàn)喚始出來(lái),PHP7終于如約而來(lái),對(duì)所有PHPer都是一件振奮人心的事。因?yàn)榭赡芎芏嘈』锇楹苡锌赡苷臀医?jīng)歷同...
    maquewy閱讀 1,820評(píng)論 0 4
  • 寫(xiě)php擴(kuò)展不僅僅只是要求會(huì)c語(yǔ)言,還需要了解php源碼。 因?yàn)樽约簩?xiě)的東西,總會(huì)有這樣那樣的缺點(diǎn),比如內(nèi)存泄...
    等哈哈咯閱讀 1,265評(píng)論 0 0

友情鏈接更多精彩內(nèi)容