原生编译

最后更新于:2022-04-02 02:32:37

[TOC] > [简书参考](https://www.jianshu.com/p/24449949e945) > [鸟哥参考](http://www.laruence.com/2009/04/28/719.html) > [php7 的扩展](https://segmentfault.com/a/1190000007575322) ## 下载php源码包 如: http://php.net/get/php-5.6.1.tar.bz2/from/a/mirror 以下内容属于php5.6 进入php的`ext` 目录,执行 `./ext_skel --extname=demo_name` ## 编写具体代码 1. `config.m4` ``` //修改成如下 PHP_ARG_WITH(hello, for hello support, [ --with-hello Include hello support]) ``` 2. ` php_demo_name.h` ```c PHP_FUNCTION(hello); //在.h 的头文件声明你要是实现的函数名 ``` 3. `demo_name.c` ``` //在中间插入你的函数名 const zend_function_entry dmeo_functions[] = { PHP_FE(confirm_dmeo_compiled, NULL) PHP_FE(hello, NULL) /*此处是自己添加的 */ PHP_FE_END }; //文件最后,加上具体实现 PHP_FUNCTION(hello) { php_printf("Hello World!\n"); RETURN_TRUE; } ``` 4. 编译安装 ``` > phpize > ./configure --with-php-config=/you/ath/bin/php-config > make > sudo make install > php -r"demo_name();"; ``` > 如果没有效果 可以重启`php-fpm` ## 分析某个自定义函数 ``` PHP_FUNCTION(self_concat){ char *str = NULL; int argc = ZEND_NUM_ARGS(); int str_len; long n; if (zend_parse_parameters(argc TSRMLS_CC, "sl", &str, &str_len, &n) == FAILURE) return; php_error(E_WARNING, "self_concat: not yet implemented"); } ``` ``` zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, …); 参数: int num_args 传递给函数的参数个数,通常做法是`ZEND_NUM_ARGS()` 来确定传递参数个数 TSRMLS_DC 为了线程安全 char *type_spec 指定了函数期望的参数类型,例子中 是"sl",定义的函数接受的每次参数都需要定义类型 类型指定符 对应的C类型 描述 l long 符号整数 d double 浮点数 s char *, int 二进制字符串,长度 b zend_bool 逻辑型(1或0) r zval * 资源(文件指针,数据库连接等) a zval * 联合数组 o zval * 任何类型的对象 O zval * 指定类型的对象。需要提供目标对象的类类型 z zval * 无任何操作的zval ``` ## 函数返回值 |设置返回值并且结束函数 | 设置返回值 | 宏返回类型和参数 | |---|---|---| |RETURN_LONG(l) | RETVAL_LONG(l) | 整数 | |RETURN_BOOL(b) | RETVAL_BOOL(b) | 布尔数(1或0)| |RETURN_NULL()| RETVAL_NULL() |NULL |RETURN_DOUBLE(d) |RETVAL_DOUBLE(d) |浮点数| |RETURN_STRING(s, dup)| RETVAL_STRING(s, dup) |字符串。如果dup为1,引擎会调用estrdup()重复s,使用拷贝。如果dup为0,就使用s| |RETURN_STRINGL(s, l, dup) |RETVAL_STRINGL(s, l, dup) |长度为l的字符串值。与上一个宏一样,但因为s的长度被指定,所以速度更快。| |RETURN_TRUE |RETVAL_TRUE |返回布尔值true。注意到这个宏没有括号。| |RETURN_FALSE| RETVAL_FALSE |返回布尔值false。注意到这个宏没有括号。| |RETURN_RESOURCE(r) | RETVAL_RESOURCE(r) | 资源句柄。| ## 函数声明(.def) 在`ext`下创建创建函数声明如`myfunc.def` ``` int hello_add(int x,int y) string hello(string x, string y) ``` 创建了两个将来可以被php调用的函数声明 在编写`.c`文件时,就自动创建了`PHP_FUNCTION(hello_add)`和`PHP_FUNCTION(hello)`. 且参数与返回值按照php的扩展标准 `php ./ext_skel.php --extname=myfunc --proto=myfunc.def` > 编译时,需要带`-proto=myfunc.def` 参数
';