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

简介: # 前言 这次,我们将演示如何在PHP扩展中接受传入的参数和输出返回值。 ``` php ``` 我们将在扩展中实现`default_value`方法。 # 代码 ## 基础代码 这个扩展,我们将在say扩展上增加 ``default_value`` 方法。say扩展相关代码大家请看这篇博文。PHP7扩展开发之hello word 文中已经详细介绍了如何创建一个扩展和提供了源

前言

这次,我们将演示如何在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方法

default_value方法的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中的相关代码。

更多函数说明请查看

目录
相关文章
ly~
|
2月前
|
存储 供应链 小程序
除了微信小程序,PHP 还可以用于开发哪些类型的小程序?
除了微信小程序,PHP 还可用于开发多种类型的小程序,包括支付宝小程序、百度智能小程序、抖音小程序、企业内部小程序及行业特定小程序。在电商、生活服务、资讯、工具、娱乐、营销等领域,PHP 能有效管理商品信息、订单处理、支付接口、内容抓取、复杂计算、游戏数据、活动规则等多种业务。同时,在企业内部,PHP 可提升工作效率,实现审批流程、文件共享、生产计划等功能;在医疗和教育等行业,PHP 能管理患者信息、在线问诊、课程资源、成绩查询等重要数据。
ly~
78 6
|
2月前
|
设计模式 算法 数据库连接
PHP中的设计模式:提高代码的可维护性与扩展性本文旨在探讨PHP中常见的设计模式及其应用,帮助开发者编写出更加灵活、可维护和易于扩展的代码。通过深入浅出的解释和实例演示,我们将了解如何使用设计模式解决实际开发中的问题,并提升代码质量。
在软件开发过程中,设计模式是一套经过验证的解决方案模板,用于处理常见的软件设计问题。PHP作为流行的服务器端脚本语言,也有其特定的设计模式应用。本文将重点介绍几种PHP中常用的设计模式,包括单例模式、工厂模式和策略模式,并通过实际代码示例展示它们的具体用法。同时,我们还将讨论如何在实际项目中合理选择和应用这些设计模式,以提升代码的可维护性和扩展性。
61 4
|
11天前
|
XML JSON API
【PHP开发专栏】PHP RESTful API设计与开发
随着互联网技术的发展,前后端分离成为Web开发的主流模式。本文介绍RESTful API的基本概念、设计原则及在PHP中的实现方法。RESTful API是一种轻量级、无状态的接口设计风格,通过HTTP方法(GET、POST、PUT、DELETE)操作资源,使用JSON或XML格式传输数据。在PHP中,通过定义路由、创建控制器、处理HTTP请求和响应等步骤实现RESTful API,并强调了安全性的重要性。
19 2
|
15天前
|
XML 安全 PHP
PHP与SOAP Web服务开发:基础与进阶教程
本文介绍了PHP与SOAP Web服务的基础和进阶知识,涵盖SOAP的基本概念、PHP中的SoapServer和SoapClient类的使用方法,以及服务端和客户端的开发示例。此外,还探讨了安全性、性能优化等高级主题,帮助开发者掌握更高效的Web服务开发技巧。
|
25天前
|
NoSQL 安全 Linux
MongoDB PHP 扩展
10月更文挑战第19天
12 0
MongoDB PHP 扩展
|
1月前
|
SQL 关系型数据库 MySQL
PHP与MySQL协同工作的艺术:开发高效动态网站
在这个后端技术迅速迭代的时代,PHP和MySQL的组合仍然是创建动态网站和应用的主流选择之一。本文将带领读者深入理解PHP后端逻辑与MySQL数据库之间的协同工作方式,包括数据的检索、插入、更新和删除操作。文章将通过一系列实用的示例和最佳实践,揭示如何充分利用这两种技术的优势,构建高效、安全且易于维护的动态网站。
|
1月前
|
Java PHP
PHP作为广受青睐的服务器端脚本语言,在Web开发中占据重要地位。理解其垃圾回收机制有助于开发高效稳定的PHP应用。
【10月更文挑战第1天】PHP作为广受青睐的服务器端脚本语言,在Web开发中占据重要地位。其垃圾回收机制包括引用计数与循环垃圾回收,对提升应用性能和稳定性至关重要。本文通过具体案例分析,详细探讨PHP垃圾回收机制的工作原理,特别是如何解决循环引用问题。在PHP 8中,垃圾回收机制得到进一步优化,提高了效率和准确性。理解这些机制有助于开发高效稳定的PHP应用。
44 3
|
1月前
|
前端开发 JavaScript 小程序
前端uni开发后端用PHP的圈子系统该 如何做源码?
圈子系统系统基于TP6+Uni-app框架开发;客户移动端采用uni-app开发,管理后台TH6开发。系统支持微信公众号端、微信小程序端、H5端、PC端多端账号同步,可快速打包生成APP
|
1月前
|
前端开发 JavaScript PHP
Thinkphp在线客服系统源码多语言外贸版_PHP客服系统源码Uniapp开发搭建+论文设计
Thinkphp在线客服系统源码多语言外贸版_PHP客服系统源码Uniapp开发搭建+论文设计
|
2月前
|
设计模式 存储 算法
PHP中的设计模式:策略模式的深入解析与应用在软件开发的浩瀚海洋中,PHP以其独特的魅力和强大的功能吸引了无数开发者。作为一门历史悠久且广泛应用的编程语言,PHP不仅拥有丰富的内置函数和扩展库,还支持面向对象编程(OOP),为开发者提供了灵活而强大的工具集。在PHP的众多特性中,设计模式的应用尤为引人注目,它们如同精雕细琢的宝石,镶嵌在代码的肌理之中,让程序更加优雅、高效且易于维护。今天,我们就来深入探讨PHP中使用频率颇高的一种设计模式——策略模式。
本文旨在深入探讨PHP中的策略模式,从定义到实现,再到应用场景,全面剖析其在PHP编程中的应用价值。策略模式作为一种行为型设计模式,允许在运行时根据不同情况选择不同的算法或行为,极大地提高了代码的灵活性和可维护性。通过实例分析,本文将展示如何在PHP项目中有效利用策略模式来解决实际问题,并提升代码质量。