PHP程序员需要略会C也是必要的,不管从业务角度还是 专业角度,因为C是PHP的母语。并且我们一般不会用原生PHP来处理大批量业务逻辑,这个时候我们需要扩展, 。
PHP从语言本质来说的确是一门不错的语言,如果灵活的运用,他不应该成为阻碍我们前进的瓶颈,反而是一把利器。
如果运用得当PHP真的是个不错的选择。
现在进入正题:
通过C扩展PHP
实现函数 Usher_GetHostIP()
该函数的功能是获取系统IP 并且返回 无参数调用
直接进入正题:
首先进入PHP源代码 的 ext目录下 执行 ./ext_skel --extname=usher 这一步产生扩展架构 执行后如下图
产生了 usher扩展目录
进入 cd usher ls 发现有如下文件 我这里是配置好的比大家多 无所谓
运行 /usr/local/php/bin/phpize 根据你的路径选择phpize 这一步是autoconfig的利用 会产生上图中的 configure
到了这一步OK 编译环境准备完毕 !!下面开始实现 我们的Usher_GetHostIP()
进入产生的usher 目录 编辑 usher.c 和php_usher.h 这两个文件是C的头文件和 源文件 我们需要在这里 扩展PHP
我直接贴上代码
打开php_usher.h 添加如下代码
PHP_FUNCTION(Usher_GetHostIP); //注意这里 这是我们自己添加的 扩展函数
结果如下
#ifndef PHP_USHER_H #define PHP_USHER_H extern zend_module_entry usher_module_entry; #define phpext_usher_ptr &usher_module_entry #define PHP_USHER_VERSION "0.1.0" /* Replace with version number for your extension */ #ifdef PHP_WIN32 # define PHP_USHER_API __declspec(dllexport) #elif defined(__GNUC__) && __GNUC__ >= 4 # define PHP_USHER_API __attribute__ ((visibility("default"))) #else # define PHP_USHER_API #endif #ifdef ZTS #include "TSRM.h" #endif PHP_MINIT_FUNCTION(usher); PHP_MSHUTDOWN_FUNCTION(usher); PHP_RINIT_FUNCTION(usher); PHP_RSHUTDOWN_FUNCTION(usher); PHP_MINFO_FUNCTION(usher); PHP_FUNCTION(confirm_usher_compiled); /* For testing, remove later. */ PHP_FUNCTION(Usher_GetHostIP); //注意这里 这是我们自己添加的 扩展函数 /* Declare any global variables you may need between the BEGIN and END macros here: ZEND_BEGIN_MODULE_GLOBALS(usher) long global_value; char *global_string; ZEND_END_MODULE_GLOBALS(usher) */ #ifdef ZTS #define USHER_G(v) TSRMG(usher_globals_id, zend_usher_globals *, v) #else #define USHER_G(v) (usher_globals.v) #endif #endif /* PHP_USHER_H */
打开usher.c添加如下代码
#include <netdb.h> //我们添加的扩展代码 #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>
//Usher_GetHostIP实现 PHP_FUNCTION(Usher_GetHostIP) { char *arg = NULL; int arg_len, len; char *strg; struct hostent *he; char hostname[20] = {0}; gethostname(hostname,sizeof(hostname)); he = gethostbyname(hostname); if (ZEND_NUM_ARGS() !=0) { RETURN_STRINGL("Prm error",strlen("Prm error") , 0); return; } len = spprintf(&strg, 0, "%s:%s", "usher", inet_ntoa(*(struct in_addr*)(he->h_addr))); RETURN_STRINGL(strg, len, 0); }
最终如下 usher.c如下
#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main/php.h" #include "main/php_ini.h" #include "ext/standard/info.h" #include "php_usher.h" #include <netdb.h> //我们添加的扩展代码 #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> static int le_usher; const zend_function_entry usher_functions[] = { PHP_FE(Usher_GetHostIP, NULL) /* For testing, remove later. */ PHP_FE(confirm_usher_compiled, NULL) /* For testing, remove later. */ PHP_FE_END /* Must be the last line in usher_functions[] */ }; /* }}} */ /* {{{ usher_module_entry */ zend_module_entry usher_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif "usher", usher_functions, PHP_MINIT(usher), PHP_MSHUTDOWN(usher), PHP_RINIT(usher), /* Replace with NULL if there's nothing to do at request start */ PHP_RSHUTDOWN(usher), /* Replace with NULL if there's nothing to do at request end */ PHP_MINFO(usher), #if ZEND_MODULE_API_NO >= 20010901 PHP_USHER_VERSION, #endif STANDARD_MODULE_PROPERTIES }; /* }}} */ #ifdef COMPILE_DL_USHER ZEND_GET_MODULE(usher) #endif PHP_MINIT_FUNCTION(usher) { return SUCCESS; } PHP_MSHUTDOWN_FUNCTION(usher) { return SUCCESS; } PHP_RINIT_FUNCTION(usher) { return SUCCESS; } PHP_RSHUTDOWN_FUNCTION(usher) { return SUCCESS; } PHP_MINFO_FUNCTION(usher) { php_info_print_table_start(); php_info_print_table_header(2, "usher support", "enabled"); php_info_print_table_end(); } //Usher_GetHostIP实现 PHP_FUNCTION(Usher_GetHostIP) { char *arg = NULL; int arg_len, len; char *strg; struct hostent *he; char hostname[20] = {0}; gethostname(hostname,sizeof(hostname)); he = gethostbyname(hostname); if (ZEND_NUM_ARGS() !=0) { RETURN_STRINGL("Prm error",strlen("Prm error") , 0); return; } len = spprintf(&strg, 0, "%s:%s", "usher", inet_ntoa(*(struct in_addr*)(he->h_addr))); RETURN_STRINGL(strg, len, 0); } PHP_FUNCTION(confirm_usher_compiled) { char *arg = NULL; int arg_len, len; char *strg; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) { return; } len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "usher", arg); RETURN_STRINGL(strg, len, 0); }
代码 修改完毕 开始编译
修改 usher目录下的config.m4 去掉下图所示的两行前的 dnl (PHP_ARG_WITH 、 [ --with-usher 这两行的dnl)
直接 ./make 在usher目录下 如下图结果 就证明编译成功
make install 安装 具体安装到哪里 看php的设置 我这里默认安装到
生成了usher.so
好了 扩展编完了 加载到 php 试试 启动 fpm 进入 phpinfo查看 我们的扩展加载了没
看吧 usher support enabled!!!!!
我们到PHP中编写代码测试吧 :
echo Usher_GetHostIP();
结果如下 我们成功的扩展了PHP