Home >php教程 >php手册 >php的扩展和嵌入--c扩展开发helloworld

php的扩展和嵌入--c扩展开发helloworld

WBOY
WBOYOriginal
2016-06-13 10:19:161330browse

在linux下面完成了LAMP的配置环境之后,就可以进行php的扩展开发了。

php中的扩展开发都在源码包的/ext文件夹之下,可以看到这里已经有了很多开发好的扩展。比如与数据库相关的mysql以及xml处理的模块等等。

首先建立一个文件夹:

mkdir hello

在进入这个文件夹之后,先创建并打开一个配置文件:

vim config.m4

这个给出一个配置问题的实例:

1 PHP_ARG_ENABLE(sample, whether to enable SAMPLE support,
2 [ --enable-sample Enable SAMPLE support])
3 if test "$PHP_SAMPLE" = "yes"; then
4    AC_DEFINE(SAMPLE, 1, [Whether you have SAMPLE])
5   PHP_NEW_EXTENSION(sample, sample.c, $ext_shared)
6 fi
* 这个配置文件创造了一个--enable-hello的配置选项,而PHP_ARG_ENABLE的第二个选项会在配置的时候显示出来
* PHP_ARG_ENABLE的第三个参数则是在调用./configurehelp的时候会显示出来
* 为什么有时候用enable-xxx,有时候用with-xxx?enable是可以关掉的,但是with需要额外的第三方的库
* 如果说--enable-hello在配置的时候有了,那么$PHP_HELLO这个参数就会被设为yes,那么才有接下来的操作
* PHP_NEW_EXTENSION则是要声明所有需要的源文件:PHP_NEW_EXTENSION(sample, sample.c sample2.c sample3.c, $ext_shared)
* 最后一个参数在building一个shared module的时候一般是这么些的。$ext_shared

下面列出在config文件中可能有的配置选项: * PHP_ARG_WITH 或者 PHP_ARG_ENABLE 指定了PHP扩展模块的工作方式,前者意味着不需要第三方库,后者正好相反;
* PHP_REQUIRE_CXX 用于指定这个扩展用到了C++;
* PHP_ADD_INCLUDE 指定PHP扩展模块用到的头文件目录;
* PHP_CHECK_LIBRARY 指定PHP扩展模块PHP_ADD_LIBRARY_WITH_PATH定义以及库连接错误信息等;
* PHP_ADD_LIBRARY(stdc++,”",EXTERN_NAME_LIBADD)用于将标准C++库链接进入扩展
* PHP_SUBST(EXTERN_NAME_SHARED_LIBADD) 用于说明这个扩展编译成动态链接库的形式;
* PHP_NEW_EXTENSION 用于指定有哪些源文件应该被编译,文件和文件之间用空格隔开;
接下来看头文件:php_sample.h
1  ?#ifndef PHP_SAMPLE_H
2  /* 防止两次引入 */
3  #define PHP_SAMPLE_H
4  /* 定义扩展的性质 */
5  #define PHP_SAMPLE_EXTNAME "sample"
6  #define PHP_SAMPLE_EXTVER "1.0"
7  /* 当在php的源码树之外build的时候,引入配置选项, 在使用phpize工具时,一般都是先定义的 */
8  #ifdef HAVE_CONFIG_H
9  #include "config.h"
10  #endif
11  /* 引入php标准头文件 */
12  #include "php.h"
13  PHP_FUNCTION(hello_world);//声明扩展中的函数
14   /* 定义入口点的符号,zend在加载这个module的时候会用*/
15  extern zend_module_entry sample_module_entry;
16  #define phpext_sample_ptr &sample_module_entry
17  #endif /* PHP_SAMPLE_H */
最后再注意两点: * php.h则是一定要引入的
* 声明zend_module_entry被声明为extern,所以当扩展被以extension=。。的形式加载的时候,Zend能够通过dlopen()和dlsym()找到它。


最后来看源文件sample.c:
#include "php_sample.h"

    static function_entry php_sample_functions[] = {
    PHP_FE(sample_hello_world, NULL)//任何扩展中的函数都要在这里声明。把函数名输出到了用户空间中
    { NULL, NULL, NULL }
    };
zend_module_entry sample_module_entry = { //创建一个入口
    #if ZEND_MODULE_API_NO >= 20010901 //这个是一个版本号
    STANDARD_MODULE_HEADER,
    #endif
    PHP_SAMPLE_EXTNAME,
    php_sample_functions, /* Functions 这里是把php_function加入到Zend中去*/
    NULL, /* MINIT */
    NULL, /* MSHUTDOWN */
    NULL, /* RINIT */
    NULL, /* RSHUTDOWN */
    NULL, /* MINFO */
    #if ZEND_MODULE_API_NO >= 20010901
    PHP_SAMPLE_EXTVER,
    #endif
    STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_SAMPLE
ZEND_GET_MODULE(sample)
#endif //这块区域是当扩展被动态加载的时候,为Zend添加一个引用,记得要添加上就行。
/*真正的函数体的部分*/
PHP_FUNCTION(sample_hello_world)
{
    php_printf("Hello World!\n");
}
这就是源码的内容了。
接下来需要进行扩展的生成: phpize ./configure --enable-sample make sudo make install 在执行完这些语句之后,需要在php.ini中添加这个扩展名:extension=sample.so 然后再重启一下apache sudo /etc/init.d/httpd restart
接下来在phpinfo页面中查看是否sample这个扩展已经有了,如果有了,那么在下面test.php中验证:
<?php
    sample_hello_world();
?>
如果打印除了"Hello World!",那么就说明这个php扩展开发成功了。

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn