文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

PHP扩展开发--入门

2023-10-11 21:43

关注

环境介绍:

        centos7、php7.4

实现功能:写个简单类,包含name属性和一个say方法;

打开PHP安装的源码包,进入/usr/local/resource/php-7.4.24/ext

        执行命令:php ext_skel.php --ext hello

        结果如下:

        

 此时在./ext目录下会多出个hello目录,进入其中

打开配置文件config.m4

        这个文件很重要,PHP系统如何构建扩展就根据它来的,配合phpize工具生成configure文件

        dnl相当于注释吧,本次扩展不依赖其他库,所以打开PHP_ARG_ENABLE就行(代码里说明

        如果所编写的扩展如果依赖其它的扩展或者lib库,就开启with)

        

        第一个参数是扩展名,第二个参数用于configure 脚本执行时输出的,AS_HELP_STRING用

        于--help时显示信息

        最底下,PHP_NEW_EXTENSION(hello, hello.c, $ext_shared)

        第二个参数为源文件,多个源文件用空格隔开,shared参数设置为$ext_shared吧

        (应该是:)),交给configure处理。。。

        其他一些M4宏方法,有兴趣的可以去细细查下,不多解释,7.4版本下,以上都是默认开启的

打开源文件hello.c

      内置了test1和test2方法,咱不管它

       (1)先摁个指针:zend_class_entry *hello_ce; 

       (2)在hello_module_entry结构体内,修改第4个参数为 PHP_MINIT(hello);

       (3)模块初始化:

                
                PHP_MINIT_FUNCTION(hello)
                {
                        zend_class_entry ce;

                        //hello为类名(切记要有双引号),hello_methods是类的行为集合
                        INIT_CLASS_ENTRY(ce, "hello", hello_methods);

                        //zend_register_internal_class返回一个指针
                        hello_ce = zend_register_internal_class(&ce);

                        //定义name属性
                        zend_declare_property_null(hello_ce, "name", sizeof("name") - 1, ZEND_ACC_PUBLIC);
                        return SUCCESS;
                }
                

        (4)行为集合,方法结构体:

                //say为行为名称,arginfo_hello_say为参数验证

                const zend_function_entry hello_methods[] = {
                        PHP_ME(hello, say, arginfo_hello_say, ZEND_ACC_PUBLIC)
                        {NULL, NULL, NULL}
                };

        (5)参数验证,定义arginfo结构体:

·                ZEND_BEGIN_ARG_INFO_EX(arginfo_hello_say, 0, 0, 1)
                        ZEND_ARG_INFO(0, name)
                        ZEND_ARG_INFO(0, other)
                ZEND_END_ARG_INFO()

                生成zend_arg_info结构的数组比较繁琐,内核已经提供了相应的宏来处理此问题。

                头部:ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference)

                           ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args)

                           前两个参数统一:name结构体名称;pass_rest_by_reference(1|0)为1时表示所有参数都要以引入的形式传递 ;return_reference(1|0)1时返回值需要以引入的形式

                           返回;required_num_args必传参数的个数

                数据:ZEND_ARG_INFO(0, name)

                           第一个参数(1|0)为1表示必须以引入的方式传递参数,此处单独配置会覆盖头部pass_rest_by_reference;第二个为参数名称

                尾部:ZEND_END_ARG_INFO()

        (6)行为方法体具体实现:        

                
                PHP_FUNCTION(hello, say)
                {
                        zend_string *name, *other, *var;

                        ZEND_PARSE_PARAMETERS_START(1, 2)
                                Z_PARAM_STR(name)
                                Z_PARAM_OPTIONAL
                                Z_PARAM_STR(other)
                        ZEND_PARSE_PARAMETERS_END();

                        var = strpprintf(0, "hello %s", ZSTR_VAL(name));
                        if(ZSTR_LEN(other) != 0){
                                var = strpprintf(0, "hello %s from %s", ZSTR_VAL(name), ZSTR_VAL(other));
                        }

                        RETURN_STR(var);
                }
                

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

                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "al|zb", &input, &offset, &z_length, &preserve_keys) == FAILURE) {

                            return;

                }

                ZEND_NUM_ARGS() TSRMLS_CC:规定传入参数的个数

                al|zb: 格式化字符串,指定传入参数与PHP内核类型的转换关系 a:zval, l:long,| 表示后面的参数可选 ,z: 表示参数是多种类型,要把传入的参数转换为zval类型,b:布尔

                FAST ZPP

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

                以ZEND_PARSE_PARAMETERS_START(1, 2)开头。

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

                以ZEND_PARSE_PARAMETERS_END();结束。

                中间是传入参数的解析。

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

                Z_PARAM_ARRAY 对应 a

                Z_PARAM_LONG 对应 l

                Z_PARAM_OPTIONAL 对应 |

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

        (7)完整代码(注意顺序):

                zend_class_entry *hello_ce;

                PHP_METHOD(hello, say)
                {       
                        zend_string *name, *other, *var;        
                        ZEND_PARSE_PARAMETERS_START(1, 2)
                        Z_PARAM_STR(name)
                        Z_PARAM_OPTIONAL
                        Z_PARAM_STR(other)
                        ZEND_PARSE_PARAMETERS_END();

                        var = strpprintf(0, "hello %s", ZSTR_VAL(name));
                        if(ZSTR_LEN(other) != 0){
                                var = strpprintf(0, "hello %s from %s", ZSTR_VAL(name), ZSTR_VAL(other));

                        }

                        RETURN_STR(var);
                }

                ZEND_BEGIN_ARG_INFO_EX(arginfo_hello_say, 0, 0, 1)
                        ZEND_ARG_INFO(0, name)
                        ZEND_ARG_INFO(0, other)
                ZEND_END_ARG_INFO()
                const zend_function_entry hello_methods[] = {
                        PHP_ME(hello, say, arginfo_hello_say, ZEND_ACC_PUBLIC)
                        {NULL, NULL, NULL}
                };


                PHP_MINIT_FUNCTION(hello)
                {
                        zend_class_entry ce;
                       INIT_CLASS_ENTRY(ce, "hello", hello_methods);
                        hello_ce = zend_register_internal_class(&ce);
                        zend_declare_property_null(hello_ce, "name", sizeof("name") - 1, ZEND_ACC_PUBLIC);
                        return SUCCESS;
                }

编译,安装 ,/usr/local/resource/php-7.4.24/ext/hello目录下

        /opt/php/bin/phpize(根据安装的PHP位置)

        ./configure --enable-hello --with-php-config=/opt/php/bin/php-config

        make && make install

        打开php.ini,添加extension=hello.so

        php -m查看是否加载hello扩展

测试

       

        

                 

来源地址:https://blog.csdn.net/jz_Orange/article/details/126838021

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯