设为首页 收藏本站
查看: 466|回复: 0

[经验分享] 实战:用C写php扩展(一)

[复制链接]

尚未签到

发表于 2017-3-27 08:53:40 | 显示全部楼层 |阅读模式
1、  前言
首先,确保你的机器安装了apache和php。假设apache的安装目录为/usr/local/apache2,php的安装目录为/usr/local/php

此外你还需要一份php源码(可以从http://www.php.net/downloads.php上获取),假设我们的php源码保存在/home/sunlylorn/php下。

2、  实战
我们要写一个php扩展:myExt
[c-sharp] view plaincopyprint?
cd /home/sunlylorn/php/ext  
ext_skel --extname=myExt  
  
cd myExt  
vi config.m4  

先来看一下一个默认的config.m4文件,如下所示:
[c-sharp] view plaincopyprint?
dnl $Id$  
dnl config.m4 for extension myExt  
  
dnl Comments in this file start with the string 'dnl'.  
dnl Remove where necessary. This file will not work  
dnl without editing.  
  
dnl If your extension references something external, use with:  
  
dnl PHP_ARG_WITH(myExt, for myExt support,  
dnl Make sure that the comment is aligned:  
dnl [  --with-myExt             Include myExt support])  
  
dnl Otherwise use enable:  
  
dnl PHP_ARG_ENABLE(myExt, whether to enable myExt support,  
dnl Make sure that the comment is aligned:  
dnl [  --enable-myExt           Enable myExt support])  
  
if test "$PHP_MYEXT" != "no"; then  
  dnl Write more examples of tests here...  
  
  dnl # --with-myExt -> check with-path  
  dnl SEARCH_PATH="/usr/local /usr"     # you might want to change this  
  dnl SEARCH_FOR="/include/myExt.h"  # you most likely want to change this  
  dnl if test -r $PHP_MYEXT/$SEARCH_FOR; then # path given as parameter  
  dnl   MYEXT_DIR=$PHP_MYEXT  
  dnl else # search default path list  
  dnl   AC_MSG_CHECKING([for myExt files in default path])  
  dnl   for i in $SEARCH_PATH ; do  
  dnl     if test -r $i/$SEARCH_FOR; then  
  dnl       MYEXT_DIR=$i  
  dnl       AC_MSG_RESULT(found in $i)  
  dnl     fi  
  dnl   done  
  dnl fi   
  dnl  
  dnl if test -z "$MYEXT_DIR"; then  
  dnl   AC_MSG_RESULT([not found])  
  dnl   AC_MSG_ERROR([Please reinstall the myExt distribution])  
  dnl fi   
  
  dnl # --with-myExt -> add include path  
  dnl PHP_ADD_INCLUDE($MYEXT_DIR/include)  
  
  dnl # --with-myExt -> check for lib and symbol presence  
  dnl LIBNAME=myExt # you may want to change this  
  dnl LIBSYMBOL=myExt # you most likely want to change this   
  
  dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,  
  dnl [  
  dnl   PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $MYEXT_DIR/lib, MYEXT_SHARED_LIBADD)  
  dnl   AC_DEFINE(HAVE_MYEXTLIB,1,[ ])  
  dnl ],[   
  dnl   AC_MSG_ERROR([wrong myExt lib version or lib not found])  
  dnl ],[   
  dnl   -L$MYEXT_DIR/lib -lm  
  dnl ])  
  dnl  
  dnl PHP_SUBST(MYEXT_SHARED_LIBADD)  
  
  PHP_NEW_EXTENSION(myExt, myExt.c, $ext_shared)  
fi  

[c-sharp] view plaincopyprint?
//修改如下三行:  
dnl PHP_ARG_ENABLE(myExt, whether to enable myExt support,  
dnl Make sure that the comment is aligned:  
dnl [  --enable-myExt           Enable myExt support])  
//为  
PHP_ARG_ENABLE(myExt, whether to enable myExt support,  
dnl Make sure that the comment is aligned:  
[  --enable-myExt           Enable myExt support])  

注解:
config.m4 文件负责在配置时解析configure 的命令行选项。凡是带有 dnl 前缀的都是注释,注释是不被解析的。
[c-sharp] view plaincopyprint?
//当然你也可以修改如下三行:  
dnl PHP_ARG_WITH(myExt, for myExt support,  
dnl Make sure that the comment is aligned:  
dnl [  --with-myExt             Include myExt support])  
//为  
PHP_ARG_WITH(myExt, for myExt support,  
dnl Make sure that the comment is aligned:  
[  --with-myExt             Include myExt support])  

不同之处在于下面调用configure编译时是使用--with-myExt还是--enable-myExt。当需要引用外部文件时使用第一个选项(就像用 -–with-apache 指令来引用 Apache 的目录一样),后者正好相反。不过,不管你使用哪一个指令,你都应该注释掉另外一个。
[c-sharp] view plaincopyprint?
phpize //执行这一步的目的是根据config.m4文件的内容生成configure文件  
  
configure --enable-myExt  
  
修改php_myExt.h与myExt.c完成功能  
  
make //这时,在myExt/modules目录就应该已经生成了myExt.so扩展模块了  
  
make install //会自动把生成的myExt.so模块拷贝到php认为正确的扩展目录,我测试的时候此目录为 /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/  
你也可以手动把myExt.so扩展拷贝到想要的目录  
  
修改php.ini文件,添加extension=myExt.so  
  
/usr/local/apache2/bin/apachectl restart //重启apache  

至此,一个最简单的php扩展我们已经完成了。下面我们来测试一下。
注意到扩展目录下存在一个名为myExt.php的文件,该文件是自动生成的。我们先来看一下该文件中的内容:
[c-sharp] view plaincopyprint?
<?php  
$br = (php_sapi_name() == "cli")? "":"<br>";  
  
if(!extension_loaded('myExt')) {            //如果没有在php.ini文件中添加extension=myExt.so  
        dl('myExt.so');                     //就需要动态加载myExt.so  
}  
$module = 'myExt';  
$functions = get_extension_funcs($module);  //获取被导出的扩展函数名,默认的导出函数为confirm_myExt_compiled()  
echo "Functions available in the test extension:$br/n";  
foreach($functions as $func) {  
    echo $func."$br/n";  
}  
echo "$br/n";  
$function = 'confirm_' . $module . '_compiled';  
if (extension_loaded($module)) {  
        $str = $function($module);  
} else {  
        $str = "Module $module is not compiled into PHP";  
}  
echo "$str/n";  
?>  
运行/usr/local/php/bin/php myExt.php  
你可以看到如下输出:  
Functions available in the test extension:  
confirm_myExt_compiled  
Congratulations! You have successfully modified ext/myExt/config.m4. Module myExt is now compiled into PHP.  

接下来,你就可以在自己的php代码中使用confirm_myExt_compiled()函数了

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-355878-1-1.html 上篇帖子: 在centos6.5-min安装php 下篇帖子: 轻量的PHP开发框架--- litePhp
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表