PHP7扩展开发之传参与返回值

 更新时间:2016年11月25日 14:55  点击:2296
下在我们来看一篇关于PHP7扩展开发之传参与返回值的例子,希望这一篇文章能够帮助到各位朋友,具体的细节如下文介绍.

前言

这次,我们将演示如何在PHP扩展中接受传入的参数和输出返回值。

<?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"));
?>
我们将在扩展中实现`default_value`方法。

代码

基础代码

这个扩展,我们将在say扩展上增加 `default_value` 方法。say扩展相关代码大家请看这篇博文。 PHP7扩展开发之hello word 文中已经详细介绍了如何创建一个扩展和提供了源码下载。

实现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(); }

代码解读

获取参数

在PHP7中提供了两种获取参数的方法。`zend_parse_parameters`和FAST ZPP方式。

zend_parse_parameters

在PHP7之前一直使用`zend_parse_parameters`函数获取参数。这个函数的作用,就是把传入的参数转换为PHP内核中相应的类型,方便在PHP扩展中使用。

参数说明:

第一个参数,参数个数。一般就使用`ZEND_NUM_ARGS()`,不需要改变。

第二个参数,格式化字符串。这个格式化字符串的作用就是,指定传入参数与PHP内核类型的转换关系。

代码中 S|z 的含义就是:

S 表示参数是一个字符串。要把传入的参数转换为zend_string类型。

| 表示之后的参数是可选。可以传,也可以不传。

z 表示参数是多种类型。要把传入的参数转换为zval类型。

除此之外,还有一些specifier,需要注意:

!如果接收了一个PHP语言里的null变量,则直接把其转成C语言里的NULL,而不是封装成IS_NULL类型的zval。

/ 如果传递过来的变量与别的变量共用一个zval,而且不是引用,则进行强制分离,新的zval的is_ref__gc==0, and refcount__gc==1.

更多格式化字符串的含义可以查看官方网站。https://wiki.php.net/rfc/fast_zpp

FAST ZPP

在PHP7中新提供的方式。是为了提高参数解析的性能。对应经常使用的方法,建议使用FAST ZPP方式。

使用方式:

以`ZEND_PARSE_PARAMETERS_START(1, 2)`开头。

第一个参数表示必传的参数格式,第二个参数表示最多传入的参数个数。

以`ZEND_PARSE_PARAMETERS_END();`结束。

中间是传入参数的解析。

值得注意的是,一般FAST ZPP的宏方法与zend_parse_parameters的specifier是一一对应的。如:

Z_PARAM_OPTIONAL 对应 |

Z_PARAM_STR 对应 S

但是,Z_PARAM_ZVAL_EX方法比较特殊。它对应两个specifier,分别是 ! 和 / 。! 对应宏方法的第二个参数。/ 对应宏方法的第三个参数。如果想开启,只要设置为1即可。

FAST ZPP相应的宏方法可以查看官方网站 https://wiki.php.net/rfc/fast_zpp#proposal

返回值

方法的返回值是使用`RETURN_`开头的宏方法进行返回的。常用的宏方法有:

RETURN_NULL() 返回null

RETURN_LONG(l) 返回整型

RETURN_DOUBLE(d) 返回浮点型

RETURN_STR(s) 返回一个字符串。参数是一个zend_string * 指针

RETURN_STRING(s) 返回一个字符串。参数是一个char * 指针

RETURN_STRINGL(s, l) 返回一个字符串。第二个参数是字符串长度。

RETURN_EMPTY_STRING() 返回一个空字符串。

RETURN_ARR(r) 返回一个数组。参数是zend_array *指针。

RETURN_OBJ(r) 返回一个对象。参数是zend_object *指针。

RETURN_ZVAL(zv, copy, dtor) 返回任意类型。参数是 zval *指针。

RETURN_FALSE 返回false

RETURN_TRUE 返回true

更多宏方法请查看 Zend/zend_API.h中的相关代码。

HTTP状态码在php中可以通过curl_getinfo函数来获得,然后进行判断了具体的我们来看这段PHP获取访问页面HTTP状态码例子吧.

今天,逐风来和大家分享一个PHP获取访问页面HTTP状态的再封装函数;

以下是关键部分代码:

/**
 * 获取远程URL的HTTP状态
 *
 * @version 0.0.1
 * @Author  Chenjl  *
 * @param string  $url       远程URL
 * @param string  $data      ture[返回HTTP状态数组] | false[返回状态数值]
 *
 * @return  mixed
 */
function getHeaders($url,$data=FALSE){
    $_headers = get_headers($url,1);
    if( !$data ){return $_headers;}
    $curl = curl_init(); 
    curl_setopt($curl,CURLOPT_URL,$url);//获取内容url 
    curl_setopt($curl,CURLOPT_HEADER,1);//获取http头信息 
    curl_setopt($curl,CURLOPT_NOBODY,1);//不返回html的body信息 
    curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);//返回数据流,不直接输出 
    curl_setopt($curl,CURLOPT_TIMEOUT,30); //超时时长,单位秒 
    curl_exec($curl); 
    $rtn= curl_getinfo($curl,CURLINFO_HTTP_CODE); 
    curl_close($curl);
    return  $rtn;
}
上面的代码,逐风已将两种获取方式进行一个整合,方便不同获取HTTP状态情景的需求;

返回结果:

# 调用案例1:getHeaders('http://www.111cn.net\/\',true);
# 返回结果:200 // 直接返回HTTP状态码
 
# 调用案例2:getHeaders('http://www.111cn.net/',false);
# 返回结果:
/*
array(10) {   
[0]=>   
string(15) "HTTP/1.1 200 OK"   
["Server"]=>   
string(5) "nginx"   
["Date"]=>   
string(29) "Mon, 04 Jul 2016 06:21:35 GMT"   
["Content-Type"]=>   
string(9) "text/html"   
["Content-Length"]=>   
string(5) "26898"   
["Last-Modified"]=>   
string(29) "Mon, 04 Jul 2016 06:16:00 GMT"   
["Connection"]=>   
string(5) "close"   
["Vary"]=>   
string(15) "Accept-Encoding"   
["ETag"]=>   
string(15) ""5779ff20-6912""   
["Accept-Ranges"]=>   
string(5) "bytes"   
}   
*/

PHP之将POST数据转化为字符串功能可以记录日志了我们这里来看一篇关于PHP之将POST数据转化为字符串的介绍.

逐风今天来分享一个方便我们做LOG日志记录的自定义函数;

主要用途就是记录POST过来的参数;

以下函数主要原理还是应用递归方式,将多维数组转化为一维数组进行,最后进行数组转字符串处理既可拿到POST过来的数据字符串化;

/**
 * 应用于LOG记录POST参数使用
 *
 * @version 0.0.1
 * @Author  Chenjl <ciwdream@gmail.com>
 *
 * @return  string
 */
function getPostLog(array $_data = array(),$n = ''){
    $_gPOST = empty($_data) ? I('post.') : $_data;
    $_rs    = array();
    foreach ($_gPOST AS $name=>$value){
        if( is_array($value) ){
            $_rs[] = getPostLog($value,$name);
        }else{
            if( !empty($_data) ){
                $_rs[] = $n.'['.$name.']'.'='.$value;
            }else{
                $_rs[] = $name.'='.$value;
            }
        }
    }
    $_rs = implode('&', $_rs);
    return $_rs;
}

定义数组在php中其实可以不管随时可以创建数组哦,下面我们来给各位介绍标准的关于php定义数组的例子吧.

1、PHP定义数组的格式

数组名=array();

如:$aa=array();//这样就定义了一个数组,

之后给元素赋值:

$aa[0]="9016";

$aa[1]="9017";

$aa[2]="9018";

2、PHP输出数组的方法:

foreach($aa as $val)

{

echo$val;

}

也可以在定义数组时直接赋值

$aa=array(0=>"9016",1=>"9017";2=>"9018");

3、PHP的数组还可以用字符做下标,不一定要数字.

$aa["name"]="Joan";

$aa["num"]="9018";

$aa["email"]="abc@abc.com";

也可以这样

$aa=array("name"=>"joan","num"=>"9018","email"=>"abc@abc.com");

将一个一维数组的元素也定义为数组,就是一个二维数组,

$aa=array(0=>"a1",1=>"a2");

$bb=array(0=>"b1",1=>"b2");

$cc=array(0=>$aa;1=>$bb);此时,$cc[0]也是一个数组,$cc[1]也是一个数组,$cc就是一个二维数组。

同理,三维,四维数组也可以继续定义下去。

4、数组的元素不仅于数字和字符串,可以是类的对象。

[!--infotagslink--]

相关文章

  • Java List集合返回值去掉中括号('[ ]')的操作

    这篇文章主要介绍了Java List集合返回值去掉中括号('[ ]')的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-29
  • Feign接口方法返回值设置方式

    这篇文章主要介绍了Feign接口方法返回值设置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-08
  • vue 中的动态传参和query传参操作

    这篇文章主要介绍了vue 中的动态传参和query传参操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-11-09
  • vue打开新窗口并实现传参的图文实例

    这篇文章主要给大家介绍了关于vue打开新窗口并实现传参的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-04
  • AngularJS的ng-click传参的方法

    本篇文章主要介绍了AngularJS的ng-click传参的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 ...2017-06-24
  • 使用Redis获取数据转json,解决动态泛型传参的问题

    这篇文章主要介绍了使用Redis获取数据转json,解决动态泛型传参的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-15
  • C# WebApi 接口传参详解

    这篇文章主要介绍了C# WebApi 接口传参详解,本篇打算通过get、post、put、delete四种请求方式分别谈谈基础类型(包括int/string/datetime等)、实体、数组等类型的参数如何传递。感兴趣的小伙伴们可以参考一下...2020-06-25
  • 基于jQuery实现收缩展开功能

    这篇文章主要介绍了基于jQuery实现收缩展开功能的相关资料,需要的朋友可以参考下...2016-03-22
  • PHP通用返回值设置

    PHP是现在很多程序比较常用的软件,一些人在写php代码时候,会遇到需要返回值的情况。这里可以统一设置下返回值格式,下面文章就给大家介绍返回值设置实例,下面一起来看看。...2017-07-06
  • Postman动态获取返回值过程详解

    这篇文章主要介绍了Postman动态获取返回值过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-30
  • vue-列表下详情的展开与折叠案例

    这篇文章主要介绍了vue-列表下详情的展开与折叠案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-29
  • 浅谈vue中$event理解和框架中在包含默认值外传参

    这篇文章主要介绍了浅谈vue中$event理解和框架中在包含默认值外传参,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-07
  • PHP7扩展开发之传参与返回值

    下在我们来看一篇关于PHP7扩展开发之传参与返回值的例子,希望这一篇文章能够帮助到各位朋友,具体的细节如下文介绍. 前言 这次,我们将演示如何在PHP扩展中接受传入的...2016-11-25
  • 详解C语言函数返回值解析

    这篇文章主要介绍了详解C语言函数返回值解析的相关资料,需要的朋友可以参考下...2020-04-25
  • C#打开php链接传参然后接收返回值的关键代码

    这篇文章主要介绍了C#打开php链接传参然后接收返回值的关键代码,代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • 微信小程序中多个页面传参通信的学习与实践

    刚接触微信小程序,对里面的语法和属性还不怎么了解,最近正在努力学习中,下面这篇文章主要给大家介绍了微信小程序中多个页面传参通信的相关资料,是最近学习的一个内容总结,需要的朋友可以参考借鉴,下面来一起看看吧。...2017-05-09
  • asp.net EXECUTENONQUERY()返回值介绍

    前些日子作一些数据项目的时候 在ADO.NET 中处理 ExecuteNonQuery()方法时,总是通过判断其返回值是否大于0来判断操作时候成功 。但是实际上并不是这样的,下面详细介绍一下,有需要的朋友可以参考...2021-09-22
  • Golang的func参数及返回值操作

    这篇文章主要介绍了Golang的func参数及返回值操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-04
  • ref 和out传参的区别分析

    今天又遇到这个问题了,问了问同事,他说最近面试的时候,也问道他了,于是给我讲了讲,现在大概是记住了,分享一下。...2020-06-25
  • axios封装与传参示例详解

    这篇文章主要给大家介绍了关于axios封装与传参的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-18