PHP扩展开发-Hello World

来源:互联网 发布:linux创建新用户和组 编辑:程序博客网 时间:2024/06/06 00:54

一、搭建骨干

PHP源码中提供了一个扩展开发工具 ext_skel,使用它能快速搭建一个扩展骨干。这个工具在 php-src/ext/ 目录下

./ext_skel --extname=hello

在控制台执行上面命令,会生成php-src/ext/hello 目录,hello就是扩展名。

目录结构如下

hello.c #是我们扩展的主要文件

config.m4 #m4是一个宏解释工具,用来生成我们扩展的makefile

php_hello.h #这个是我们扩展的头文件

tests/001.phpt #这个是个测试文件,使用的是单元测试,阶段测试

hello.php 模块测试文件,用于测试模块是否正确加载。

config.m4中包含了大量的dnl开头的行,表示是被注释掉的内容,删除不需要的内容,打开第10,11,12行,修改后的内容如下,
–enalle-hello 表示启用 hello模块

PHP_ARG_ENABLE(varstream, whether to enable varstream support,[  --enable-hello           Enable hello support])if test "$PHP_HELLO" != "no"; then  PHP_NEW_EXTENSION(hello, hello.c, $ext_shared)fi

在控制台执行 phpize 他会初始化PHP编译环境。
然后 ./configure & make
这样,模块就生成完毕。

此时,我们没有写任何代码,这个骨干里面包含了一个测试函数,
运行hello扩展目录下的 hello.php文件,它能测试模块是否已经被加载

php hello.php

二,导出HelloWorld方法

观察以下结构,这是扩展模板中默认的一个测试函数。

PHP_FUNCTION(confirm_hello_compiled){    char *arg = NULL;    int arg_len, len;    char *strg;    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {        return;    }    len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "hello", arg);    RETURN_STRINGL(strg, len, 0);}

PHP_FUNCTION(confirm_hello_compiled) 表示定义了一个函数,confirm_hello_compiled为函数名。

现在,需要添加一个函数,输出Hello World,模仿以上,不难写出以下代码

PHP_FUNCTION(hello){    php_printf("Hello World");}

php_printf 与C语言中 printf类似。

仅仅这些是不够的,虽然定义了需要的函数,但是没有任何一个地方说明了这个函数要干什么,如果要让用户空间能使用,至少需要导出才行。
在hello.c文件中,有如下结构,hello_module_entry,按照字面意思,就是hello模块的入口。

zend_module_entry hello_module_entry = {    STANDARD_MODULE_HEADER,    "hello",    hello_functions,    PHP_MINIT(hello),    PHP_MSHUTDOWN(hello),    PHP_RINIT(hello),       /* Replace with NULL if there's nothing to do at request start */    PHP_RSHUTDOWN(hello),   /* Replace with NULL if there's nothing to do at request end */    PHP_MINFO(hello),    PHP_HELLO_VERSION,    STANDARD_MODULE_PROPERTIES};

第一个参数 STANDARD_MODULE_HEADER, 标准模块头,既然是标准,那就不要动这个。
第二个参数 “Hello”,就是模块的名字
第三个参数 hello_functions 就是模块中导出的方法。
申明如下:

const zend_function_entry hello_functions[] = {    PHP_FE(confirm_hello_compiled,  NULL)       /* For testing, remove later. */    PHP_FE_END  /* Must be the last line in hello_functions[] */};

可以看到,confirm_hello_compiled在其中,为了导出我们的方法hello,模仿以上写法即可,

const zend_function_entry hello_functions[] = {    PHP_FE(confirm_hello_compiled,  NULL)    PHP_FE(hello,   NULL)    PHP_FE_END  /* Must be the last line in hello_functions[] */};

后面的参数,暂时不用考虑,和hello模块,暂时没啥联系,后续再讲。

到这里,方法就对外可用了,于是 make ,可以在 hello/modules下面找到编译好的扩展。

三、使用

首先,需要PHP去加载创建的Hello模块
在php.ini中加入这个模块即可。

extention=xxxx/xxx/hello.so

修改配置文件后,需要重启web容器,可以在phpinfo()中找到hello模块信息。

既然模块已经导出了hello函数,那就和 PHP提供的普通函数一样使用就可以了。创建一个php脚本hello.php,如下

<?php    hello();?>

在控制台执行 php hello.php 即可看到熟悉的 Hello World.

0 0
原创粉丝点击