最近在看 《PHP扩展开发中文教程》
的pdf版。PHP的解释器是用C语言写的,因此PHP扩展天然也是用C 语言
了。php
用过php的人必定也用过php扩展。php自己带有86个扩展,扩展是对php语言功能的一个延伸,php的核心由两部分组成:最底层的 Zend引擎
和 PHP内核
。ze把脚本解析成机器可读的符号,也会处理内存管理,变量做用域,程序调度。PHP内核则主要涉及主机环境(Apache,IIS,Nginx),处理与主机的通讯。编程
当php自身不知足需求的时候就能够本身去造轮子了。采用C语言开发还能必定程度上解决性能问题,而php是我最喜欢的一门编程语言,写扩展的机会天然不放过,更重要的是能够 装逼
。php7
咱们要写个扩展代替如下的功能:编程语言
<?php function hello() { return 'hello world'; }
个人开发环境是:工具
系统: Ubuntu 16.04性能
PHP: 7.0+测试
gcc :4.8.4
PHP已经提供了工具用来建立扩展,并初始化代码:ext_skel
spa
$ cd php-src/ext $ ./ext_skel --extname=hello
工具会在当前目录生成 hello
文件夹。code
cd到hello,工具已经初始化了目录,打开配置文件 config.m4
:blog
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_H extern 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 ZTS ZEND_TSRMLS_CACHE_DEFINE() #endif ZEND_GET_MODULE(world) #endif
编译安装:
$ phpize $ ./configure --with-php-config=/usr/local/php7/bin/php-config $ make & make install
测试:
同样须要在php.ini
添加extension=world.so
不使用工具的精简的一个扩展完成。