Linux/FreeBSD下用C语言开发PHP的so扩展模块例解

Show All   1 2

引用本文请注明出处:Just Do IT (http://www.toplee.com) < Michael Lee @ toplee.com >

我从97年接触互联网的web开发,至今已经过去9年了,从最初的frontpage做html页面到学会ASP+access+IIS开始,就跟web开发干上了,后来又依次使用了ASP+SQLServer+IIS、JSP+Oracle+Jrun(Resin/Tomcat)、PHP+Syabse(MySQL)+Apache … 最后我定格到了 PHP+MySQL+Apache+Linux(BSD) 的架构上,也就是大家常说的LAMP架构,这说来有很多理由,网上也有很多人讨论各种架构和开发语言之间的优劣,我就不多说了,简单说一下我喜欢LAMP的几个主要原因:

1、全开放的免费平台;
2、简单易上手、各种资源丰富;
3、PHP、MySQL、Apache与Linux(BSD)系统底层以及彼此间无缝结合,非常高效;
4、均使用最高效的语言C/C++开发,性能可靠;
5、PHP语言和C的风格基本一致,还吸取了Java和C++的诸多架构优点;
6、这是最关键的一点,那就是PHP可以非常方便的使用C/C++开发扩展模块,给了PHP无限的扩张性!

基于以上原因,我非常喜欢基于PHP语言的架构,其中最关键的一点就是最后一点,以前在Yahoo和mop均推广使用这个平台,在C扩展php方面也有一些经验,在此和大家分享一下,希望可以抛砖引玉。

用C语言编写PHP的扩展模块的方法有几种,根据最后的表现形式有两种,一种是直接编译进php,一种是编译为php的so扩展模块来被php调用,另外根据编译的方式有两种,一种使用phpize工具(php编译后有的),一种使用ext_skel工具(php自带的),我们使用最多,也是最方便的方式就是使用ext_skel工具来编写php的so扩展模块,这里也主要介绍这种方式。

我们在php的源码目录里面可以看到有个ext目录(我这里说的php都是基于Linux平台的php来说的,不包括windows下的),在ext目录下有个工具 ext_skel ,这个工具可以让我们简单的开发出php的扩展模块,它提供了一个通用的php扩展模块开发步骤和模板。下面我们以开发一个在php里面进行utf8/gbk/gb2312三种编码转换的扩展模块为例子进行说明。在这个模块中,我们要最终提供以下几个函数接口:

(1) string toplee_big52gbk(string s)
将输入字符串从BIG5码转换成GBK
(2) string toplee_gbk2big5(string s)
将输入字符串从GBK转换成BIG5码
(3) string toplee_normalize_name(string s)
将输入字符串作以下处理:全角转半角,strim,大写转小写
(4) string toplee_fan2jian(int code, string s)
将输入的GBK繁体字符串转换成简体
(5) string toplee_decode_utf(string s)
将utf编码的字符串转换成UNICODE
(6) string toplee_decode_utf_gb(string s)
将utf编码的字符串转换成GB
(7) string toplee_decode_utf_big5(string s)
将utf编码的字符串转换成BIG5
(8) string toplee_encode_utf_gb(string s)
将输入的GBKf编码的字符串转换成utf编码

首先,我们进入ext目录下,运行下面命令:
#./ext_skel –extname=toplee
这时,php会自动在ext目录下为我们生成一个目录toplee,里面包含下面几个文件
.cvsignore
CREDITS
EXPERIMENTAL
config.m4
php_toplee.h
tests
toplee.c
toplee.php

其中最有用的就是config.m4和toplee.c文件
接下来我们修改config.m4文件
#vi ./config.m4
找到里面有类似这样几行

dnl PHP_ARG_WITH(toplee, for toplee support,
dnl Make sure that the comment is aligned:
dnl [  --with-toplee             Include toplee support])

dnl Otherwise use enable:

dnl PHP_ARG_ENABLE(toplee, whether to enable toplee support,
dnl Make sure that the comment is aligned:
dnl [  --enable-toplee           Enable toplee support])

上面的几行意思是说告诉php编译的使用使用那种方式加载我们的扩展模块toplee,我们使用–with-toplee的方式,于是我们修改为下面的样子

PHP_ARG_WITH(toplee, for toplee support,
Make sure that the comment is aligned:
[  --with-toplee             Include toplee support])

dnl Otherwise use enable:

dnl PHP_ARG_ENABLE(toplee, whether to enable toplee support,
dnl Make sure that the comment is aligned:
dnl [  --enable-toplee           Enable toplee support])

然后我们要做的关键事情就是编写toplee.c,这个是我们编写模块的主要文件,如果您什么都不修改,其实也完成了一个php扩展模块的编写,里面有类似下面的几行代码

PHP_FUNCTION(confirm_toplee_compiled)
{
        
char *arg = NULL;
        
int arg_len, len;
        
char string[256];
 
        
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
                
return;
        
}
 
        
len = sprintf(string, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "toplee", arg);
        
RETURN_STRINGL(string, len, 1);
}

如果我们在后面完成php的编译时把新的模块编译进去,那么我们就可以在php脚本中调用函数toplee(),它会输出一段字符串“Congratulations! You have successfully modified ext/toplee/config.m4. Module toplee is now compiled into PHP.”

Show All   1 2
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
16 Responses
  1. Ken says:

    不知道楼主对 Python + TurboGears(或Django) 看法如何,感觉 PHP 的代码和 HTML 源码混在一起看起来很累,页面和代码没有分离的很好。

  2. Michael says:

    我对python没有什么研究,基本不太了解,但是知道这是个很不错的语言,有机会想了解一下。
    php代码和html的分离已经在基于php的架构中广泛使用,著名的有编译到php里面的smarty模板引擎,还要用php来写的PHPLib模板引擎等,这些都可以轻松的实现html和php代码的分离,比如我现在用的这个wordpress Blog程序就是应用了模板引擎,可以随意的更换皮肤(风格)和更换界面的语言版本。

  3. chenn says:

    看了你的几篇文章,写的挺不错的,尤其是”说说大型高并发高负载网站的系统架构”,与我们的服务系统采用的方案比较类似,收获不少, 在此表示感谢:).

  4. kING says:

    “编译到php里面的smarty模板引擎”
    有编译版本的SMARTY??

  5. Michael says:

    呵呵,笔误,当时脑子里面想到了早期研究过的一个PHP的Cache引擎,好像是俄罗斯人写的一个编译到php里面的cache引擎。smarty不用编译,也没有编译版本的,如果有一天php语言可以强到可以使用php本身编写扩展的时候,就能把smarty编译进去了。。。:)

  6. cqf820 says:

    不错,写的蛮详细,这文章找了好久。先去实验下
    谢谢

  7. cqf820 says:

    请教个问题: 如果C那边给我提供了一个xxx.so文件,我用php调用xxx.so的接口,且传递参数过去, 这个该怎么做。
    或者需要把C代码都放到xxx.c里面去.

  8. Michael says:

    [Comment ID #2386 Will Be Quoted Here]

    需要把代码放进去,就是我范例里面的toplee.c文件,也可以自己加一些.c文件进去,然后在toplee.c里面调用头件。

  9. says:

    俊哥你好,我今天第一次您的bolg,感觉很不错。
    由于工作需要开始做php。看到有smarty的讨论,我说两句,smarty是个很重要的技术,我刚从java转到php的时候要不是看到它,早就崩溃了(页面和代码混合编写)。
    虽然这篇文章是06年的,但相关内容我最近才开始研究,打算自己试试,遇到问题还请赐教。

  10. dyfire says:

    楼主好文章啊,写的很全,非常感谢,大胡子~:)

  11. Michael says:

    [Comment ID #21976 Will Be Quoted Here]

    呵呵,希望对您能有一些借鉴的帮助,谢谢关注!:)

  12. nogroup says:

    如果我的php是Freebsd下ports安装的,就无法开发扩展了吗?

  13. 网页游戏 says:

    如果我会php的话我就用cms模版好好改一个网页游戏门户网站出来,php真的太强大了

  14. 网页游戏 says:

    c语言真的很不错哈 ,呵呵

  15. zhou says:

    php中如何向so库中传递和接收struct 可以发个实例给我吗

  16. zhou says:

    我的QQ是349215180加我QQ也可以啊 希望你能尽快的回答我

Leave a Reply

Your email address will not be published. Required fields are marked *

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Anti-spam image