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();
利用C/C++扩展php语言实现 Usher_GetHostIP无参函数
原文:http://blog.csdn.net/yue7603835/article/details/43462955