玩了php开发有段时间了,得感谢抚琴居(可惜访问不到了), 风雪之隅, 特别感谢benxi 的指导(本来写c 就少, 让我理解了一些基本概念)。
准备写一些php 扩展开发相关的文章, 让知识延续吧。
先来个helloworld 吧。
代码应该不难理解, 简单说一下:
包含进了php 的基本头文件和开发扩展要到的头文件, 申明了模块的入口zend_module_entry phpext_module_entry,定义了模块的函数zend_function_entry phpext_functions
在几个模块相关的函数
ZEND_MINIT_FUNCTION(phpext); 模块初始化
ZEND_MSHUTDOWN_FUNCTION(phpext); 模块结束处理
ZEND_RINIT_FUNCTION(phpext); 请求初始化
ZEND_RSHUTDOWN_FUNCTION(phpext); 请求结束
顺序是 MINT -> RINIT -> RSHUTDOWN -> MSHUTDOWN
在这里我申明了一个常量
REGISTER_STRING_CONSTANT(“CONST_HELLOWORLD”, “helloworld”, CONST_CS | CONST_PERSISTENT);
安装: make && make install 剩下的你懂的,
test.php
helloworld();
echo CONST_HELLOWORLD;
phpext.h
#ifndef PHP_PHPEXT_H
#define PHP_PHPEXT_H
#define PHPEXT_VERSION "0.8"
#define PHPEXT_MICRO_IN_SEC 1000000.00
#include "php.h"
#include "main/php_version.h"
#include "main/php_config.h"
#include "zend.h"
#include "zend_API.h"
#include "zend_hash.h"
#include "zend_constants.h"
#include "TSRM.h"
extern zend_module_entry phpext_module_entry;
#define phpext_phpext_ptr &phpext_module_entry
/**
* 模块 global 变量
*/
ZEND_BEGIN_MODULE_GLOBALS(phpext)
ZEND_END_MODULE_GLOBALS(phpext)
#ifdef ZTS
#define PHPEXT_G(v) TSRMG(phpext_globals_id, zend_phpext_globals *, v)
#else
#define PHPEXT_G(v) (phpext_globals.v)
#endif
//获取 执行时间信息
double phpext_get_utime(void);
static void php_phpext_init_globals(zend_phpext_globals *phpext_globals TSRMLS_DC);
static void php_phpext_shutdown_globals(zend_phpext_globals *phpext_globals TSRMLS_DC);
ZEND_MINIT_FUNCTION(phpext);
ZEND_MSHUTDOWN_FUNCTION(phpext);
ZEND_RINIT_FUNCTION(phpext);
ZEND_RSHUTDOWN_FUNCTION(phpext);
ZEND_MINFO_FUNCTION(phpext);
#ifdef ZEND_ENGINE_2
ZEND_MODULE_POST_ZEND_DEACTIVATE_D(phpext);
#endif
ZEND_FUNCTION(helloworld);
#endif
phpext.c
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include "php.h"
#include "zend.h"
#include "TSRM.h"
#include "zend_alloc.h"
#include "zend_ini.h"
#include "zend_API.h"
#include "ext/standard/info.h"
#include "phpext.h"
ZEND_DECLARE_MODULE_GLOBALS(phpext)
ZEND_GET_MODULE(phpext)
// 定义模块函数
zend_function_entry phpext_functions[] = {
ZEND_FE(helloworld, NULL)
{NULL, NULL, NULL}
};
// 定义模块入口
zend_module_entry phpext_module_entry = {
STANDARD_MODULE_HEADER,
"phpext",
phpext_functions,
ZEND_MINIT(phpext),
ZEND_MSHUTDOWN(phpext),
ZEND_RINIT(phpext),
#ifdef ZEND_ENGINE_2
ZEND_RSHUTDOWN(phpext),
#else
NULL,
#endif
ZEND_MINFO(phpext),
PHPEXT_VERSION,
#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 2) || PHP_MAJOR_VERSION >= 6
NO_MODULE_GLOBALS,
#endif
#ifdef ZEND_ENGINE_2
ZEND_MODULE_POST_ZEND_DEACTIVATE_N(phpext),
#else
NULL,
#endif
STANDARD_MODULE_PROPERTIES_EX
};
/**
* 注册函数
*/
ZEND_FUNCTION(helloworld) {
php_printf("helloworld");
RETURN_TRUE;
}
ZEND_INI_BEGIN()
ZEND_INI_END()
static void php_phpext_init_globals(zend_phpext_globals *phpext_globals TSRMLS_DC) {
}
static void php_phpext_shutdown_globals(zend_phpext_globals *phpext_globals TSRMLS_DC) {
}
/**
* 模块初始化, Module Initialization,apache 启动的时候初始化模块,适合于初始模块的全局变量,常量
*/
ZEND_MINIT_FUNCTION(phpext) {
//定义常量 CONST_HELLOWORLD
REGISTER_STRING_CONSTANT("CONST_HELLOWORLD", "helloworld", CONST_CS | CONST_PERSISTENT);
ZEND_INIT_MODULE_GLOBALS(phpext, php_phpext_init_globals, php_phpext_shutdown_globals);
REGISTER_INI_ENTRIES();
return SUCCESS;
}
/**
* 模块结束处理, Module Shutdown, apache 关闭或者一个cli SAPIs 执行结束
*/
ZEND_MSHUTDOWN_FUNCTION(phpext) {
UNREGISTER_INI_ENTRIES();
#ifdef ZTS
ts_free_id(phpext_globals_id);
#else
php_phpext_shutdown_globals(&phpext_globals TSRMLS_CC);
#endif
return SUCCESS;
}
/**
* 请求初始化 , Request Initialization, 一个新的cgi 请求的时候调用
*/
ZEND_RINIT_FUNCTION(phpext) {
return SUCCESS;
}
/**
* 请求结束, Request Shutdown
*/
ZEND_RSHUTDOWN_FUNCTION(phpext) {
return SUCCESS;
}
/**
* 在php info 里打印的模块信息
*/
ZEND_MINFO_FUNCTION(phpext) {
php_info_print_table_start();
php_info_print_table_row(2, "version", PHPEXT_VERSION);
php_info_print_table_end();
}
ZEND_MODULE_POST_ZEND_DEACTIVATE_D(phpext) {
return SUCCESS;
}
makefile
PHP_DIR = /usr/local/php
PHP_INC = $(PHP_DIR)/include/php
PHP_EXT = /usr/local/php/extensions
VPATH =
PROFILE_FOG_VER = 0.2.6
LIBC_VER = $(shell ls /lib/libc-*.so | cut -c11-13)
GCC_VER = $(shell gcc -v 2>&1 | grep "gcc version" | cut --characters="13 15 17")
TAR_OBJ = phpext.o
TAR_SYM = phpext.so
TAR_EXT = $(TAR_SYM).$(PROFILE_FOG_VER).libc.$(LIBC_VER)
INC_SYS = -I/usr/include
LNK_SYS = -L/usr/lib64 -rdynamic
#LNK_SYS = -L/usr/lib -rdynamic #32 bit arch
INC_PHP = -I$(PHP_INC) -I$(PHP_INC)/main -I$(PHP_INC)/TSRM -I$(PHP_INC)/Zend
LNK_PHP =
INC = $(INC_PHP) $(INC_SYS)
LIB = $(LNK_SYS)
CC = gcc
CFLAG = -g -fpic -DCOMPILE_DL=1 -Wall
LFLAG = -g -shared -m64
#LFLAG = -shared #32 bit arch
all: $(TAR_EXT)
$(TAR_EXT): $(TAR_OBJ)
ifneq ($(PHP_DIR),)
$(CC) $(LFLAG) -o $(TAR_EXT) $(TAR_OBJ) $(INC) $(LIB)
@echo $@
else
@echo -e "\n Canceled. \n"
endif
static: $(TAR_OBJ)
$(CC) $(LFLAG) -static -o $(TAR_EXT) $(TAR_OBJ) $(INC) $(LIB)
@echo $@
%.o: %.c %.h
ifneq ($(PHP_DIR),)
$(CC) $(CFLAG) -c $*.c $(INC)
@echo $@
else
@echo -e "\n Canceled. \n"
endif
clean:
rm -f *.o
rm -f *.so*
rm -f $(PHP_EXT)/$(TAR_SYM).*
install:
cp $(TAR_EXT) $(PHP_EXT)/$(TAR_EXT)
@echo
@echo Module has been installed to: $(PHP_EXT)/$(TAR_SYM)
@echo
uninstall:
rm -f $(PHP_EXT)/(TAR_SYM).*