构建一个简单的php扩展
2016-12-09 15:55
656 查看
构建一个简单的php扩展
基本步骤1 ./ext_skel --extname=myext 2 修改 config.m4文件 去掉这几行前面的dl PHP_ARG_ENABLE(myext, whether to enable myext support, Make sure that the comment is aligned: [ --enable-myext Enable myext support]) 3 ./phpize生成扩展的模块 4 修改php_myext.h文件 新增一行(定义函数) PHP_FUNCTION(myext_self_concat); 5 在mytexc.c中注册函数 const zend_function_entry myext_functions[] = { PHP_FE(myext_self_concat,NULL) PHP_FE(confirm_myext_compiled, NULL) PHP_FE_END }; 6 编写函数代码 PHP_FUNCTION(myext_self_concat){ char *arg = NULL; int arg_len, len; char *strg; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) { return; } php_printf("myext_self_concat\n"); RETURN_TRUE; } 7 ./configure && make && make install 8 在php的配置上加上扩展 如果没有配置文件自己加一个比如我的/Users/kang/Documents/CProject/php566/lib/php.ini /Users/kang/Documents/CProject/software/bin/php -m 查看模块 9 运行扩展中的函数 查看扩展的函数 /Users/kang/Documents/CProject/software/bin/php -r "print_r(get_extension_funcs('myext'));" 使用扩展的函数 /Users/kang/Documents/CProject/software/bin/php -r "myext_self_conc
构建一个简单的扩展需要掌握的知识
在网上找了一些知识,我觉得条目不够清楚,所以做了一个整理对php的运行机制有个基本的理解
一切的php都从SAPI Server Application Programming Interface开始运行 在SAPI下面是各种模式 例如cli php的执行流程,以我的扩展为例子: PHP_MINIT(ext_start1), PHP_MSHUTDOWN(ext_start1), PHP_RINIT(ext_start1), PHP_RSHUTDOWN(ext_start1), 在多进程挂起的情况下可能是: PHP_MINIT 后不会PHP_RSHUTDOWN 然后PHP_RINIT,加载脚本,执行程序,最后PHP_MSHUTDOWN php的线程安全: 抽象层:TSRM(Thread Safe Resource Management) 线程安全模块和非线程模块有点不一样,我觉得主要是锁的问题,如果是多线程模式, 资源需要加锁,抽象层就是锁等等进行了封装和集中处理
对php里面变量的表示有个基础的了解
每个变量都会做些类似的转换struct _zval_struct { zvalue_value value; /* 变量的值 */ zend_uint refcount__gc; zend_uchar type; /* 变量当前的数据类型 */ zend_uchar is_ref__gc; }; typedef struct _zval_struct zval; //在Zend/zend_types.h里定义的: typedef unsigned int zend_uint; typedef unsigned char zend_uchar; typedef union _zvalue_value { long lval; /* long value */ double dval; /* double value */ struct { char *val; int len; } str; HashTable *ht; /* hash table value */ zend_object_value obj; } zvalue_value;
函数接收参数
zend_parse_parameters() 读取函数的值 TSRMLS_CC TSRM表示Thread Safe Resource Manager,可能跟线程安全有关 例如: zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"l", &foo) == FAILURE TSRMLS_CC TSRM相关的宏---这个坑待我以后看看 ZEND_NUM_ARGS()表示参数的个数 type_spec是格式化字符串,其常见的含义如下: 参数 代表着的类型 b Boolean l Integer 整型 d Floating point 浮点型 s String 字符串 r Resource 资源 a Array 数组 o Object instance 对象 O Object instance of a specified type 特定类型的对象 z Non-specific zval 任意类型~ Z zval**类型 f 表示函数、方法名称,PHP5.1里貌似木有... ... 读取字符串变量: char *name; int name_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&name, &name_len) == FAILURE) { RETURN_NULL(); }
为变量分配内存
C语言原生函数 void *malloc(size_t count); void *calloc(size_t count); void *realloc(void *ptr, size_t count); void *strdup(void *ptr); void free(void *ptr); PHP内核封装后的函数 -- 带p表示永久性 void *emalloc(size_t count); void *pemalloc(size_t count, char persistent); void *ecalloc(size_t count); void *pecalloc(size_t count, char persistent); void *erealloc(void *ptr, size_t count); void *perealloc(void *ptr, size_t count, char persistent); void *estrdup(void *ptr); void *pestrdup(void *ptr, char persistent); void efree(void *ptr); void pefree(void *ptr, char persistent);
返回结果
咱们可能任务返回结果一遍得这么写ZEND_FUNCTION(sample_long_wrong) { zval *retval; MAKE_STD_ZVAL(retval); ZVAL_LONG(retval, 42); return retval; }
其实我们可以,php已经帮我们做好了上述的工作
PHP_FUNCTION(sample_long) { RETVAL_LONG(42); //展开后相当与ZVAL_LONG(return_value, 42); return; }
参考资料:
TIPI项目:http://www.php-internals.com/book/ 挖路项目:http://www.cunmou.com/phpbook/ 鸟哥的博客 http://www.laruence.com/2009/04/28/719.html 我的博客 http://www.beckbi.cn/?p=328
相关文章推荐
- 一个简单php扩展介绍与开发教程
- 一个最简单的php的C扩展
- 详细介绍附代码:使用jquery,和php文件构建一个简单的在线聊天室,通过ip显示googlemap
- 一个简单的PHP扩展
- php 5.6版本中编写一个PHP扩展的简单示例
- 编写一个简单的php扩展
- 一个简单php扩展介绍与开发
- php 5.6版本中编写一个PHP扩展的简单示例
- 创建一个简单的PHP扩展
- 编写一个简单的php扩展
- 构建一个资源类型的php扩展(二)
- 创建一个简单的php扩展
- PHP扩展开发:一个简单的例子
- 一个简单php扩展介绍与开发教程
- 一个用php3编写的简单计数器
- (Python编程)一个简单的C扩展模块
- 一个用php3编写的简单计数器
- 一个简单的php实现的MySQL数据浏览器
- 我自己用PHP写的一个极简单的 HTML 框架。