vs2015+php扩展+php.h,第一个有些作用的PHP扩展

第一个有点作用的PHP扩展

C/C++去开发PHP扩展

我觉的对于PHP开发人员来说,学的东西非常杂,也非常多,当然了开发PHP扩展也是一个必须要掌握的技能,这里膜拜下大神鸟哥(Laruence)~

今天要开发的第一个有点功能的扩展,主要作用是记录日志的时候生成日志前面的日期部分

#即使当前的时间,年-月-日 时:分:秒 时间戳.微妙数

[2015-05-19 20:39:32 1432039172.968199]

php扩展函数前奏

首先生成”骨架“:

1. 进入php源码src/ext目录下面

2. 运行./ext_skel --extname=mytest

3. 进入src/ext/mytest/目录

4. 在编写扩展的时候要先修改下config.me文件的10-12行,去掉前面的dnl注释,这个网上一搜一大把。

在头文件php_mttest.h中声明要编写的php扩展函数名

PHP_FUNCTION(get_log_title);

#PHP_FUNCTION是PHP内核中声明的一个宏

#define PHP_FUNCTION ZEND_FUNCTION //在文件src/main/php.h : 347行

#define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))//文件src/Zend/zend_API.h : 68行

#define ZEND_FN(name) zif_##name//文件src/Zend/zend_API.h : 65行

#define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS)//文件src/Zend/zend_API.h : 67行

#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC//src/Zend/zend.h : 290行

上面的声明函数宏展开后是:

void zif_get_log_title( int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC)

在mytest.c中的zend_function_entry声明中添加get_log_title函数的声明

const zend_function_entry logs_functions[] = {

PHP_FE(confirm_logs_compiled, NULL) /* For testing, remove later. */

PHP_FE(get_log_title, NULL)

PHP_FE_END /* Must be the last line in logs_functions[] */

};

#编写函数

PHP_FUNCTION(get_log_title)

{

struct timeval tv;

time_t rawtime;

struct tm *timeinfo;

char *formatinfo;

time(&rawtime);

timeinfo = localtime(&rawtime);

gettimeofday(&tv, NULL);

spprintf(&formatinfo, 0, "[%4d-%02d-%02d %d:%d:%d %d.%d]", 1900 + timeinfo->tm_year, 1 + timeinfo->tm_mon, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, tv.tv_sec, tv.tv_usec);

RETURN_STRING(formatinfo, 1);

}

这里还要看个宏RETURN_STRING

#define RETURN_STRING(s, duplicate) { RETVAL_STRING(s, duplicate); return; }//文件src/Zend/zend_API.h : 635行

#define RETVAL_STRING(s, duplicate) ZVAL_STRING(return_value, s, duplicate)//文件src/Zend/zend_API.h : 623行

#define ZVAL_STRING(z, s, duplicate) do {\//文件src/Zend/zend_API.h : 577-583行,这个的作用其实是给一个string类型zval变量赋值

const char *__s=(s);\

zval *__z = (z);\

Z_STRLEN_P(__z) = strlen(__s);\//设置zval字符串长度

Z_STRVAL_P(__z) = (duplicate?estrndup(__s, Z_STRLEN_P(__z)):(char*)__s);\//设置zval字符串的值

Z_TYPE_P(__z) = IS_STRING;\//设置zval字符串的类型为字符串

} while (0)

因此,RETURN_STRING(formatinfo, 1)展开后为:

do {

const char *__s=(formatinfo);

zval *__z = (return_value);//这里面的return_value估计是内核定义的,类似 zval *return_value;

(*__z).value.str.len = strlrn(__s);//等价于__z->value.str.len

(*__z).value.str.val = (1?estrndup(__s, (*__z).value.str.len):(char*)__s);

(*__z).type = 6;

}

编译测试

编译的时候需要安装好的php,比如我的php安装在/usr/local/php/目录下面

cd mytest;//今日刚才编写的函数扩展目录

/usr/local/php/bin/phpize //运行phpize,生成configure文件

./configure --with-php-config=/usr/local/php/bin/php-config //configure,后面的--with-php-config会生成so文件到安装好的扩展目录,当然也可以不用加,声称之后手动copy过去

make//有错误的话修正

make install //运行之后会提示类似下面的内容

#Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/

#修改配置文件php.ini添加extension = mytest.so

#测试

php -r 'var_dump(log_get_title());'

输出下面内容的话,恭喜你成功了

[root@iforever logs]# php -r 'var_dump(get_log_title());' && date

string(39) "[2015-05-19 22:52:29 1432047149.755613]"

2015年 05月 19日 星期二 22:52:29 CST

5/19/2015 10:54:38 PM

本文版权归作者iforever(luluyrt@163.com)所有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值