第一个有点作用的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)所有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
第一个有点作用的PHP扩展的更多相关文章
- Linux下脚本文件第一行的作用
Linux下脚本文件第一行的作用 在Linux/Unix系统中,你可以在脚本hello.py顶部添加以下命令让Python脚本可以像SHELL脚本一样可直接执行: #! /usr/bin/env py ...
- 安全测试6_Web安全工具第一节(浏览器入门及扩展)
今天来学习下浏览器的功能,浏览器是我们经常用到但是功能却很强大的一个东东,我们经常用到的无非是三种(谷歌.火狐.IE) 1.浏览器功能介绍: 下面以谷歌浏览器(Chrome版本为56)为例,介绍下,懂 ...
- PHP扩展开发(1):入门
有关PHP扩展开发的文章.博客已经很多了,比较经典的有: TIPI项目(http://www.php-internals.com/,强烈推荐) <Extending and Embedding ...
- Struts2第一天
Struts2第一天 整体课程安排:3天知识点+2天练习 第一天:入门(action和result结果集)--一般的请求+响应 第二天:请求数据处理相关(参数接收.类型转换.合法性校验.国际化) 第三 ...
- SQL Server 扩展事件(Extented Events)从入门到进阶(4)——扩展事件引擎——基本概念
本文属于 SQL Server 扩展事件(Extented Events)从入门到进阶 系列 在第一二节中,我们创建了一些简单的.类似典型SQL Trace的扩展事件会话.在此过程中,介绍了很多扩展事 ...
- C#编程(六十一)------------LINQ中的扩展方法
原文链接: http://blog.csdn.net/shanyongxu/article/details/47208401 LINQ中的扩展方法 LINQ中where扩展方法,要想使用,必须导入us ...
- php扩展开发-快速上手
系统环境CentOS release 6.5 (Final) PHP版本php-5.6.27 扩展开发需要有php环境及php的源代码,我的PHP安装目录/home/zhangxiaomin/stud ...
- XAML实例教程系列 - 标记扩展(Markup Extensions) 六
XAML实例教程系列 - 标记扩展(Markup Extensions) 分类: Windows 8 Silverlight2012-06-21 13:00 1139人阅读 评论(0) 收藏 举报 扩 ...
- Mysql优化(出自官方文档) - 第一篇(SQL优化系列)
Mysql优化(出自官方文档) - 第一篇 目录 Mysql优化(出自官方文档) - 第一篇 1 WHERE Clause Optimization 2 Range Optimization Skip ...
随机推荐
- php-fpm 启动参数及重要配置详解
约定几个目录 /usr/local/php/sbin/php-fpm /usr/local/php/etc/php-fpm.conf /usr/local/php/etc/php.ini 一,php- ...
- 拿到腾讯实习offer的前后小事
一.前言 本文应该算不上是面经,仅仅是自己近期一路走过的些许琐碎小事,欢迎园友吐槽,但是不要太凶残哦. 二.旧年小事 去年11月底,从上海实习公司请假回校参加研究生毕业论文开题答辩,在校忙碌了一段时间 ...
- Vue学习笔记-1
前言 本文不是Vue.js的教程,只是一边看官网Vue的教程文档一边记录并总结学习过程中遇到的一些问题和思考的笔记. 1.vue和avalon一样,都不支持VM初始时不存在的属性 而在Angular里 ...
- grootjs 简明教程
grootJs简明教程 mvvm框架也是解决的一类问题,在某些时候会提高生产效率: 经过接近一个月的努力,grootJs测试版终于发布了 grootJs是一个mvvm的框架,名字取 grass 和ro ...
- SSH登录之后运行命令报错的解决办法-- Failed to connect to Mir: Failed to connect to server socket: No such file or directory
问题描述: Failed to connect to Mir: Failed to connect to server socket: No such file or directory 解决方案: ...
- pageEncoding与contentType属性
1图例分析 由图中可以看出,这个两个属性没有任何关系. 把这两个设置成不同的编码格式对中文显示不会产生任何影响 2.原因分析 pageEncoding规定了以什么编码方式存储和读取,使两者保持一致性, ...
- MVC认知路【点点滴滴支离破碎】【一】----新建数据库
1.App_Data文件夹创建[SQL Server Compact Local Database *]数据库 2.添加链接字符串<add name="MovieDBContext&q ...
- LVS+MYCAT+读写分离+MYSQL主备同步部署手册
LVS+MYCAT+读写分离+MYSQL主备同步部署手册 1 配置MYSQL主备同步…. 2 1.1 测试环境… 2 1.2 配置主数据库… 2 1.2.1 ...
- 模块加载(require)及定义(define)时的路径
最近新公司在用requireJS进行JS的整合,刚开始接触有点蒙,于是深入了解了一下.requireJS主要是为了解决一下两个问题: (1)实现js文件的异步加载,避免网页失去响应: (2)管理模块之 ...
- vmware 在NAT模式下连接上外网
文章: http://www.2cto.com/os/201504/389011.html