PHP7拓展开发(一):hello world-演道网

本网站用的阿里云ECS,推荐大家用。自己搞个学习研究也不错

起步

最近在看 《PHP拓展开发中文教程》 的pdf版。PHP的解释器是用C语言写的,所以PHP拓展自然也是用C 语言了。

拓展是什么

用过php的人一定也用过php拓展。php本身带有86个拓展,拓展是对php语言功能的一个延伸,php的核心由两部分组成:最底层的 Zend引擎 和 PHP内核 。ze把脚本解析成机器可读的符号,也会处理内存管理,变量作用域,程序调度。PHP内核则主要涉及主机环境(Apache,IIS,Nginx),处理与主机的通信。

动机

当php自身不满足需求的时候就可以自己去造轮子了。采用C语言开发还能一定程度上解决性能问题,而php是我最喜欢的一门编程语言,写拓展的机会自然不放过,更重要的是可以 装逼 。

新建拓展

我们要写个拓展代替以下的功能:

<?php function hello() {    return 'hello world';
}

我的开发环境是:

  • 系统: Ubuntu 16.04

  • PHP: 7.0+

  • gcc :4.8.4
    PHP已经提供了工具用来创建拓展,并初始化代码:ext_skel

$ cd php-src/ext
$ ./ext_skel --extname=hello

工具会在当前目录生成 hello 文件夹。

修改配置文件

cd到hello,工具已经初始化了目录,打开配置文件 config.m4:

dnl If your extension references something external, use with:

dnl PHP_ARG_WITH(hello, for hello support,
dnl Make sure that the comment is aligned:
dnl [  --with-hello             Include hello support])dnl Otherwise use enable:

dnl PHP_ARG_ENABLE(hello, whether to enable hello support,
dnl Make sure that the comment is aligned:
dnl [  --enable-hello           Enable hello support])

dnl 是注释符,表示当前行是注释。这段话是说如果此拓展依赖其他拓展,去掉PHP_ARG_WITH段的注释符;否则去掉PHP_ARG_ENABLE段的注释符。显然我们不依赖其他拓展或lib库,所以去掉PHP_ARG_ENABLE段的注释符:

PHP_ARG_ENABLE(hello, whether to enable hello support,
Make sure that the comment is aligned:
[  --enable-hello           Enable hello support])

书写代码

工具生成的hello.c,写上我们的实现:

PHP_FUNCTION(hello)
{
    zend_string *strg;
    strg = strpprintf(0, "hello world.");
    RETURN_STR(strg);
}

添加到编译列表里:

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

编译与安装

$ phpize
$ ./configure --with-php-config=/usr/local/php7/bin/php-config
$ make & make install

修改php.ini,开启拓展,若找不到可以用phpinfo()查看使用哪个配置文件.

extension=hello.so

写个脚本:<?php echo hello(); 不出意外就能看到输出了。

额外:不使用工具写拓展

一个拓展(为避免与写过的hello冲突,采用world作为名字),至少包含3个文件: config.m4、 php_world.h 、 world.c 。一个是phpize用来准备编译拓展的配置文件,一个是引用包含的头文件,一个是源码文件。

config.m4

PHP_ARG_ENABLE(world, whether to enable world support,
Make sure that the comment is aligned:
[  --enable-world           Enable hello support])if test "$PHP_WORLD" != "no"; then
    AC_DEFINE(HAVE_WORLD,1,[ ])
    PHP_NEW_EXTENSION(world, world.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)fi

php_world.h

#ifndef PHP_WORLD_H#define PHP_WORLD_Hextern zend_module_entry hello_module_entry;#define phpext_hello_ptr &hello_module_entry#define PHP_WORLD_VERSION "0.1.0"#define PHP_WORLD_EXTNAME "world"#endif

world.c

#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "php.h"#include "php_world.h"PHP_FUNCTION(world)
{
    zend_string *strg;
    strg = strpprintf(0, "hello world. (from world module)");
    RETURN_STR(strg);
}const zend_function_entry world_functions[] = {
    PHP_FE(world, NULL)
    PHP_FE_END
};
zend_module_entry world_module_entry = {
    STANDARD_MODULE_HEADER,
    PHP_WORLD_EXTNAME,
    world_functions,    NULL,    NULL,    NULL,    NULL,    NULL,
    PHP_WORLD_VERSION,
    STANDARD_MODULE_PROPERTIES
};#ifdef COMPILE_DL_WORLD#ifdef ZTSZEND_TSRMLS_CACHE_DEFINE()#endifZEND_GET_MODULE(world)#endif

编译安装:

$ phpize
$ ./configure --with-php-config=/usr/local/php7/bin/php-config
$ make & make install

测试:
一样需要在php.ini添加extension=world.so

不使用工具的精简的一个拓展完成。

本文由 hongweipeng 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

微信扫描二维码,关注PHP技术大全!

让知识地带无限蔓延!

转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn

未经允许不得转载:演道网 » PHP7拓展开发(一):hello world-演道网

赞 (0)
分享到:更多 ()