如何写PHP扩展

作者:老王

PHP扩展的生成框架(ext_skel)已经很方便了,今天我发现一个选项可以让开发过程更方便。

./ext_skel –help

./ext_skel –extname=module [–proto=file] [–stubs=file] [–xml[=file]]
[–skel=dir] [–full-xml] [–no-help]

  –extname=module   module is the name of your extension
–proto=file       file contains prototypes of functions to create
  –stubs=file       generate only function stubs in file
–xml              generate xml documentation to be added to phpdoc-cvs
–skel=dir         path to the skeleton directory
–full-xml         generate xml documentation for a self-contained extension
(not yet implemented)
–no-help          don’t try to be nice and create comments in the code
and helper functions to test if the module compiled

首先,编写一个proto文件:

vi foo.proto

内容如下(注意行尾没有分号):

int fun_a(string str_a, string str_b)
int fun_b(int int_a, int int_b)

软后生成扩展:

./ext_skel –extname=foo –proto=foo.proto

然后看看生成的文件:

vi php_foo.h

你会发现相应的内容已经被自动添加了:

PHP_FUNCTION(confirm_foo_compiled); /* For testing, remove later. */
PHP_FUNCTION(fun_a);
PHP_FUNCTION(fun_b);

vi foo.c

/* {{{ foo_functions[]
*
* Every user visible function must have an entry in foo_functions[].
*/
zend_function_entry foo_functions[] = {
PHP_FE(confirm_foo_compiled,    NULL)       /* For testing, remove later. */
PHP_FE(fun_a,   NULL)
PHP_FE(fun_b,   NULL)
{NULL, NULL, NULL}  /* Must be the last line in foo_functions[] */
};

/* {{{ proto int fun_a(string str_a, string str_b)
*/
PHP_FUNCTION(fun_a)
{
char *str_a = NULL;
char *str_b = NULL;
int argc = ZEND_NUM_ARGS();
int str_a_len;
int str_b_len;

    if (zend_parse_parameters(argc TSRMLS_CC, "ss", &str_a, &str_a_len, &str_b, &str_b_len) == FAILURE)
return;

    php_error(E_WARNING, "fun_a: not yet implemented");
}
/* }}} */

/* {{{ proto int fun_b(int int_a, int int_b)
*/
PHP_FUNCTION(fun_b)
{
int argc = ZEND_NUM_ARGS();
long int_a;
long int_b;

    if (zend_parse_parameters(argc TSRMLS_CC, "ll", &int_a, &int_b) == FAILURE)
return;

    php_error(E_WARNING, "fun_b: not yet implemented");
}
/* }}} */

可以看到,相应的代码都已经自动加上了。

如果我们在foo.proto里加入

int fun_c(resource res_a, array arr_b[, int int_c])

那么:

/* {{{ proto int fun_c(resource res_a, array arr_b [, int int_c])
*/
PHP_FUNCTION(fun_c)
{
int argc = ZEND_NUM_ARGS();
int res_a_id = -1;
long int_c;
zval *res_a = NULL;
zval *arr_b = NULL;

    if (zend_parse_parameters(argc TSRMLS_CC, "ra|l", &res_a, &arr_b, &int_c) == FAILURE)
return;

    if (res_a) {
ZEND_FETCH_RESOURCE(???, ???, res_a, res_a_id, "???", ???_rsrc_id);
}

    php_error(E_WARNING, "fun_c: not yet implemented");
}
/* }}} */

可以看到,可选参数也判断出来了,很智能。

转自:   转自: http://hi.baidu.com/thinkinginlamp/blog/item/7c691f3030084099a9018e1b.html

参考资料(推荐):

http://talks.php.net/show/extending-php-apachecon2003/

http://blog.csdn.net/taft/archive/2006/02/10/596291.aspx

扩展示例: http://hi.baidu.com/icej/blog/item/d624d4fdbdeefb4ed7887d86.html

留下评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据