怎么写一个php扩展,如何编写一个php扩展

每一个php扩展的构建至少需要两个文件: 一个configuration文件, 它告诉编译期要构建哪些文件以及需要什么外部的库, 还需要至少一个源文件, 它执行实际的工作.

剖析扩展

实际上, 通常会有第二个或第三个配置文件, 以及一个或多个头文件. 对于你的第一个扩展, 你需要添加每种类型的一个文件并使用它们工作.

配置文件

要开始了, 首先在你的php源代码目录树的ext/目录下创建名为sample的目录. 实际上这个新的目录可以放在任何地方, 但是为了在本章后面演示win32和静态构建选项, 我们还是先建立在源代码目录下吧.

下一步, 进入这个目录, 创建一个名为config.m4的文件, 键入下面内容:PHP_ARG_ENABLE(sample,

[Whether to enable the "sample" extension],

[ enable-sample Enable "sample" extension support])

if test $PHP_SAMPLE != "no"; then

PHP_SUBST(SAMPLE_SHARED_LIBADD)

PHP_NEW_EXTENSION(sample, sample.c, $ext_shared)

fi

这是./configure时能够调用enable-sample选项的最低要求.PHP_ARG_ENABLE的第二个参数将在./configure处理过程中到达这个扩展的配置文件时显示. 第三个参数将在终端用户执行./configure --help时显示为帮助信息.

有没有想过为什么有的扩展配置使用enable-extname, 而有的扩展则使用with-extname? 功能上两者没有区别. 实际上, enable表示启用这个特性不需要其他任何第三方库, 相比之下, with则表示要使用这个特性还有其他先决条件

现在, 你的sample扩展并不需要和其他库链接, 因此只需要使用enable版本. 在第17章"外部库"中, 我们将介绍使用with并指示编译器使用额外的CFLAGS和LDFLAGS设置.

如果终端用户使用enable-sample选项调用了./configure, 那么本地的环境变量$PHP_SAMPLE, 将被设置为yes. PHP_SUBST()是标准autoconf的AC_SUBST()宏的php修改版, 它在将扩展构建为共享模块时需要.

最后但并不是不重要的, PHP_NEW_EXTENSION()定义了模块并枚举了所有必须作为扩展的一部分编译的源文件. 如果需要多个文件, 它可以在第二个参数中使用空格分隔列举, 例如:

PHP_NEW_EXTENSION(sample, sample.c sample2.c sample3.c, $ext_shared)

最后一个参数是对应于PHP_SUBST(SAMPLE_SHARED_LIBADD)命令的, 在构建共享模块的时候同样需要它.

头文件

当使用C开发的时候, 将数据的类型定义放到外部的头文件中隔离起来, 由源文件包含是常见的做法. 尽管php并不要求这样, 但是这样做在模块增长到不能放到单个源文件时是有简化作用的.

在你的php_sample.h头文件中, 以下面内容开始:#ifndef PHP_SAMPLE_H

/* 防止重复包含 */

#define PHP_SAMPLE_H

/* 定义扩展的属性 */

#define PHP_SAMPLE_EXTNAME "sample"

#define PHP_SAMPLE_EXTVER "1.0"

/* 在php源码树外面构建时引入配置选项 */

#ifdef HAVE_CONFIG_H

#include "config.h"

#endif

/* 包含php的标准头文件 */

#include "php.h"

/* 定义入口点符号, Zend在加载这个模块的时候使用 */

extern zend_module_entry sample_module_entry;

#define phpext_sample_ptr &sample_module_entry

#endif /* PHP_SAMPLE_H */

这个头文件完成了两个主要的任务: 如果扩展使用phpize工具构建(本书通常都使用这种方式), 那么HAVE_CONFG_H就是已定义的, 这样config.h就会被正常的包含进来. 无论扩展怎样编译, 都会从php源码树中包含php.h. 这个头文件中包含了php源码中访问大部分PHPAPI要使用的其他头文件.

接下来, 你的扩展使用的zend_module_entry结构定义为外部的, 这样当这个模块使用extension=xxx加载时, 就可以被Zend使用dlopen和dlsym()取到.

头文件中还会包含一些预处理, 定义将在原文件中使用的信息.

源代码

最后, 最重要的你需要在sample.c中创建一个简单的源码骨架:#include "php_sample.h"

zend_module_entry sample_module_entry = {

#if ZEND_MODULE_API_NO >= 20010901

STANDARD_MODULE_HEADER,

#endif

PHP_SAMPLE_EXTNAME,

NULL, /* Functions */

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值