环境:
下载php-devel-x.x.x.rpm 安装
下载php-x.x.x.tar
注意:这两个工具要求版本一致。
创建扩展:
解压 : tar xzvf php-x.x.x.tar
cd /php-x.x.x/ext
./ext_skel --extname=lyy :创建名为lyy的扩展模块
cd lyy
vim comfig.m4
去掉16 18行注释:
16: PHP_ARG_ENABLE(hello, whether to enable hello support,
17: dnl Make sure that the comment is aligned:
18: [ --enable-hello Enable hello support])
或者
10: PHP_ARG_WITH(my_ext, for my_ext support,
11: dnl Make sure that the comment is aligned:
12: [ --with-my_ext Include my_ext support])
保存退出
修改源码:
1:直接运行
# /usr/bin/phpize 生成configure 路径可能不同 find -name phpize 找一下
# ./configure 生成makefile
# make && make install 生成module/lyy.so 拷贝到/usr/lib64/php/modles下
# vim /etc/php.ini 添加lyy.so 库
添加两行:
externsion_dir = "/usr/lib64/php/modules/"
externsion = lyy.so
保存退出
注意:在php-5.3.3必须再php.ini中写 因为该版本不提供dl(“name.so”);加载项
# service httpd restart 重启使内核加载该库
# cd /var/www/html/ 测试
vim test.php
# dl("lyy"); //如果不是5.3.3版本可以这样加载并且上面可以不修改php.ini 否则不要这句 会报错。
echo confirm_lyy_compiled("lyy");
?>
保存退出
在浏览器地址行:127.0.0.1/test.php 刷新 就会出现Congratulations! you have successfully modified ext.......................into PHP.
2:
加载C的库函数
同上面cd /php-x.x.x/ext/lyy/
vim lyy.c 直接添加源码
PHP_FUNCTION(confirm_lyy_complied)
{
len = spprintf(...........................................);这句换成需要调用的C函数 当然传入参在arg中
换成
strg = string_handle(arg); C的字符串处理函数 在C的动态库中
RETURN_STRING(STRG,0); 不知道返回值长度,如果知道RETURN_STRINGL(strg, len,0);
}
保存退出 make LDFALGS=-ltest && make install (test是C的动态库) 重启httpd && 测试。
注意:
1:调用的C函数需要声明(例如:string_handle), 在php_lyy.h中也需要声明
2:C的动态库保证是在ld.so.conf.d指定的路径的或者# echo 动态库路径 > /etc/ld.so.conf.d
我因为这个纠结了好几天 如果修改了ls.so.conf.d之后要ldconfig 从新加载该库
同上重新测试。
关于从浏览器中测试的日志可以在/var/log/http/error_log看到
我之前在该log下出现了段错误,是RETURN_LOGN的问题
3:
另添加函数
同上面cd /php-x.x.x/ext/lyy/
vim lyy.c 增加部分
1:
zend_function_entry hello_functions[] = {
PHP_FE(confirm_hello_compiled, NULL) /* For testing, remove later. */
PHP_FE(lyy, NULL) /*新添加的库扩展. */
{NULL, NULL, NULL} /* Must be the last line in hello_functions[] */};
}
2:
然后在PHP_EF(confirm_hello_compiled)函数后面添加函数:
PHP_FUNCTION(lyy)
{
long int a, b;
long int result;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &a, &b) == FAILURE) {
return;
} //获得参数a b
result = data_handle(a, b); //处理数字类型
RETURN_LONG(result);
}
保存退出,make LDFALGS=-ltest && make install (test是C的动态库) 重启httpd 测试。
2:
PHP_FUNCTION(confirm_hello_compiled); /* For testing, remove later. */
PHP_FUNCTION(hello_add);
C的动态库制作:
# vim lyy.c 编辑C函数 注意包含相应的头文件 保存退出
# gcc lyy.c -o liblyy.so -fPIC -shared -lotherlib
或者
gcc -o -c -fPIC -o hello.o && gcc -shared -o liblyy.so hello.o -lotherlib
测试程序的编译:gcc -o exe -llyy lyytest.c 即调用库函数 生成exe
遇到的问题、同事的解释和解决办法:
1:
IMAP(www1@t.com):Error:PHP Warning:PHP Startup:Unable to load dynamic library '/usr/lib64/php/modules/hrsa.so' - libssl.so.6:cannot open shared object file:NO such file or directory in Unknow on line 0
原因:该问题是因为openssl的版本问题造成的,安全操作系统5.4系统自带的openssl版本是0.9, 而安全操作系统6的openssl版本为1.0。请尝试将系统的libssl.so文件做一个软链接,链接到libssl.so.6试试
2:
php.ini配置;
添加:
enable_dl = On
extension_dir = "/usr/lib64/php/modules/"
extension=hrsa.so
extension=lyy1.so //我测试用的 测试正常
在/var/www/html/目录下
test1.php:
dl("hrsa.so");
$ret=pwd_gate_hrsa("123456");
echo $ret;
echo "lyy===================";
?>
运行:php test1.php
报错:
[root@cs2c html]# php test1.php
PHP Warning: PHP Startup: hrsa: Unable to initialize module
Module compiled with module API=20060613
PHP compiled with module API=20090626
These options need to match
in Unknown on line 0
PHP Warning: PHP Startup: hrsa: Unable to initialize module
Module compiled with module API=20060613
PHP compiled with module API=20090626
These options need to match
in Unknown on line 0
PHP Warning: dl(): hrsa: Unable to initialize module
Module compiled with module API=20060613
PHP compiled with module API=20090626
These options need to match
in /var/www/html/test1.php on line 2
PHP Fatal error: Call to undefined function pwd_gate_hrsa() in /var/www/html/test1.php on line 3
[root@cs2c html]#
原因:这个问题你首先需要确定一下php版本,制作hrsa.so的时候,当前系统上安装的php包和php-devel包必须为同一版本。
3:PHP_FUNCTION(confirm_hrselyy_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;
} //这个地方是php传给c的入口参数,你需要按照它的规则把php传进来的参数接收过来
/*你可以在这里添加你的c代码, 比如调用libhrsa.so库里的pwd_gate_hrsa函数什么的*/
RETURN_STRINGL(strg, len, 0); //这里是c需要返回给php的返回值,同样需要按照它的规则转换成php可以识别的
}
因为制作这个php的扩展so需要调用到/lib64下的libhrsa.so,所以你需要在编译php扩展so的时候,在make命令后面加上
LDFLAGS=-lhrsa即可, 这样:make LDFLAGS=-lhrsa
4:
[root@cs2c html]# php hrsa.php
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/test.so' - /usr/lib64/php/modules/test.so: undefined symbol: pwd_gate_hrsa in Unknown on line 0
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/hrsa.so' - /usr/lib64/php/modules/hrsa.so: undefined symbol: pwd_gate_hrsa in Unknown on line 0
PHP Fatal error: Call to undefined function confirm_hrsa_compiled() in /var/www/html/hrsa.php on line 2
[root@cs2c html]#
找不到这个函数
原因:编译的时候不报错,运行时提示找不到函数,是因为环境变量的问题。你把生成的libhwrsa.so和libswsds.so拷贝一份到/usr/lib64/下,再拷贝一份到/lib64下面吧,拷贝完后执行ldconfig命令更新一下 或者拷贝到/etc/ld.so.conf.d/下指定的路径下即可
好像没落下什么 以后有进展再续写......