自己动手用 C 扩展 PHP

来源:互联网 发布:linux文本编辑 编辑:程序博客网 时间:2024/05/16 07:31

 

[ZT]自己动手用 C 扩展 PHP

引言:
   有感于大多数人认为 PHP 只是一种弱类型,只能做小型web应用的脚本语言。 与目前的Java, .Net平台有一定的差距,所以决定写一些 PHP 的扩展方法文章,我相信
我们PHPER们通过自己动手写商业扩展,一定能构建出强大的,极速的Web应用,因为扩展本身就是编译型语言编写的(c/c++),而且可以
预先驻留内存的(Apache启动时加载),有了 C/C++ 编写的扩展,我们几乎可以无所不能.
   呵呵,Zend 的说明文档少之又少,真令人头疼 
----------------------------------------------------------

环境要求:  Linux, GCC


首先,我们应该选择如何去构建我们的扩展模块, 有三种方式:
         1. External Modules
        外部模块,也就是编译成共享库,用dl()函数动态加载。
        好处:    (1)不需要重新编译 PHP (2)PHP体积小,因为不需要编译进PHP
        缺点:     (1)每次*.php脚本执行都需要用 dl()去加载,效率较低
               (2)每次都要调用dl()
    2. Built-in Modules
        编译进PHP
        好处:    (1)不需要动态加载,模块在php脚本里面可以直接使用.
            (2)不需要将模块编译成.so共享库,因为直接编译进PHP。
        缺点:    (1)对模块的改变都需要重新编译PHP
            (2)因为编译进PHP,所以PHP二进制文件较大,而且多占点内存
    3. The Zend Engine
        Zend 核心里实现        (略 ... 有兴趣的话可以看 Zend API)

Note: 本人推荐用 第 2 种方式,直接编译进PHP, 但是在下面示例里,我们编译成外部模块
    ,因为,外部模块不需要重新编译 PHP,所以在测试阶段先编译成共享库,然后用dl()
    加载(不过记得在php.ini里将安全模式设为 Off),测试完后再用第2种方式重新编译进    PHP.

1. 首先下载 PHP 源代码, 解压。 然后我们开始构建代码结构,可以利用 PHP 源代码包ext目录里提供的 ext_skel 程序去生成我们需要的结构.

    [ext]#./ext_skel --extname=haosoft_php_module

这样会在ext下生成一个 haosoft_php_module 目录。
目录里有 config.m4, haosoft_php_module.h, haosoft_php_module.c 等几个文件。

2. haosoft_php_module.h 为模块的头文件(熟悉C语言的应该了解),  用 VI 打开,删除其中的一行:
    PHP_FUNCTION(confirm_MyExt_compiled);    /* For testing, remove later. */
改为:
    PHP_FUNCTION(haosoft_test);    /* For testing, remove later. */
说明:
    PHP_FUNCTION() 是一个 Zend Macro,作用是声名一个 C 函数,使他在 PHP 脚本里可用, 参数    是函数的名字,我们这里的示例函数为 haosoft_test.

3. haosoft_php_module.c 为主文件,里面包含了实现, VI 打开,我们删除掉
PHP_FUNCTION(confirm_MyExt_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.", "haosoft_php_module", arg);
    RETURN_STRINGL(string, len, 1);
}
增加:
PHP_FUNCTION(haosoft_test) {
    zend_printf("This is my php module !";
}

4. 现在,我们开始编译我们的模块,因为要编译成 so,我们选择手工编译。
进入 ext 目录:

开始编译,编译成*.o对象文件,注意这个"-DCOMPILE_DL_HAOSOFT_PHP_MODULE",

在 haosoft_php_module.c 里你可以找到下面的语句

#ifdef COMPILE_DL_HAOSOFT_PHP_MODULE
ZEND_GET_MODULE(haosoft_php_module)
#endif

HAOSOFT_PHP_MODULE 是大写模块名,你可以换成其他名,但是必须保证这个预处理常量与
上面的语句里一致,至于上面语句的 ZEND_GET_MODULE(haosoft_php_module) 我们将在下一篇文
章讲解它的意思.

[ext]# cc -fpic -DCOMPILE_DL_HAOSOFT_PHP_MODULE=1 -I/usr/local/include -I. -I../main -I.. -I../TSRM -I../Zend -c -o haosoft_php_module/haosoft_php_module.o haosoft_php_module/haosoft_php_module.c

执行完之后会在 目录下生成一个haosoft_php_module.o文件,接下来 连接:
[ext]#  cc -shared -L/usr/local/lib -rdynamic -o haosoft_php_module/haosoft_php_module.so haosoft_php_module/haosoft_php_module.o

这样会在目录下生成了我们需要的 haosoft_php_module.so 文件。
然后我们要建立一个目录
[ext]# mkdir -p /usr/local/php/lib/php/extensions/no-debug-non-zts-20041030
上面的 20041030 的号码是Zend内部模块API号码,如果你不知道的话,你先建立一个php文
件:
test.php

<?
dl("abc.so";
?>

在浏览器里运行该文件会出现错误信息, 可以在错误信息里得到这个号码,请根据自己情况根据这个号码与你的PHP安装目录更改路径。

建立完目录后接下来,我们把haosoft_php_module.so移动到刚刚的目录里去
[ext]# mv haosoft_php_module/haosoft_php_module.so /usr/local/php/lib/php/extensions/no-debug-non-zts-20041030

OK! 我们可以测试刚建立的模块了,目前模块里只有一个 haosoft_test() 的无参数方法。

建立 php 文件:

test.php

<?php
// 加载刚建立的模块
dl("haosoft_php_module.so";
// 调用函数
haosoft_test();
?>

执行。 看到显示 "This is my module !" 了吗?

5. 好了,模块编译,并测试无误后,我们可以将他编译进 PHP 了,回到 PHP源代码包根目录
执行:
[php-5.0.6]#./buildconf --force
[php-5.0.6]#./configure --enable-haosoft_php_module ... 也许你还有其他选项
[php-5.0.6]#make
[php-5.0.6]#make install
[php-5.0.6]#sh /etc/init.d/httpd restart   ... 这里是重启 apache

---------------------------------------------------------------
本示例在我 PHP5.0.6 上编译通过,  下一章我们再详细分析 haosoft_php_module.h, haosoft_php_module.c 这两个文件里的内容,以及有参数,有返回值函数的定义及使用.
4 点了,偶该睡觉了! 有时间再写下一章。 希望以上内容对大家会有所帮助!

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 oppor忘记锁屏图案怎么办 oppor手机忘记解锁图案怎么办 oppor手机忘记图案了怎么办 oppo手机屏幕锁忘了怎么办 三星手机屏幕锁忘了怎么办 手机主菜单坏了怎么办 索尼手机密码忘了怎么办 索尼笔记本密码忘了怎么办 索尼手机解锁密码忘了怎么办 索尼记录仪密码忘了怎么办 索尼z3手机忘记开机密码怎么办 索尼忘记锁屏密码怎么办 索尼手机忘记锁屏密码怎么办 忘了手机解锁图案怎么办 索尼手机忘记开机密码怎么办 索尼笔记本开机密码忘了怎么办 手机的开机密码忘了怎么办 联想手机开机密码忘了怎么办 红米note3忘记开机密码怎么办 小米2忘了密码怎么办 小米笔记本电脑忘记开机密码怎么办 小米笔记本忘记开机密码怎么办 小米手机儿童模式忘记密码怎么办 小米应用锁密码忘了怎么办 小米air密码忘了怎么办 小米4密码忘了怎么办 小米手机开机密码忘了怎么办? 小米笔记本电脑开机密码忘了怎么办 小米笔记本开机密码忘了怎么办 htc手机忘记解锁图案怎么办 红米手机屏幕锁定怎么解锁怎么办 小米5s有id怎么办 手机密码找不回来了怎么办? 手机密码图案忘了怎么办 手机屏幕图案锁忘了怎么办 捡到苹果7有id锁怎么办 魅族什么都忘了怎么办 海信电视百事通登陆失败怎么办 去哪儿换号了怎么办 ipan充不进去电怎么办 安卓数据线松了怎么办