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);
- PHP_FUNCTION(Usher_GetHostIP);
-
-
-
-
-
-
-
-
-
-
- #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>
-
- 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)
- PHP_FE(confirm_usher_compiled, NULL)
- PHP_FE_END
- };
-
-
-
-
- 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),
- PHP_RSHUTDOWN(usher),
- 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();
-
- }
-
- 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中编写代码测试吧 :
结果如下 我们成功的扩展了PHP