PHP 扩展实战

 

1 前言

        

  • 主要目的让大家了解一下怎么做PHP语言的扩展,仍然以上次叙述的Perl的扩展的例子——获得IP来源地址为例。

 

2 前提条件

        

  • 假设你已经拥有了 LAMP (Linux+Apache+Mysql+PHP的缩写),并假设其安装路径分别是:

        

  • 目前所叙述的实例可能与 mysql 没有太多的关系,所以无关紧要,但是 PHP 是必须安装的;
  •     

  • 另外,需要 PHP 的源码,如果你没有,可以去 http://www.php.net 获取 PHP 源码,其源码路径位:

        

  • 末了说句,本实例完全在 Linux 64 位平台下演示,若有出入,可以随时联系笔者。

 

3 流程及步骤

        

  • 其实制作PHP扩展非常简单, ext_skel 命令的帮助已说明得非常详细,如下所示:

        

  • 尝试着创建一个扩展 getaddress

        

  • 上面的后续的帮助步骤已经说得比较清楚,一共 8 个步骤;

 

4 详细过程描述

4.1 建立扩展目录

        

  • 方便的 ext_skel 命令能帮助建立一个扩展模型 getaddress ,系统会自动建立一个 getaddress 目录,其文件会相应的生成在 getaddress 目录内;

4.2 描述及编辑config.m4

        

  • ext_skel 建立的目录里面一般有 config.m4 这个文件,这里面有一些基础的宏定义:    
              

    • dnl 是注释;
    •         

    • PHP_ARG_WITH 或者 PHP_ARG_ENABLE 指定了PHP扩展模块的工作方式;
    •         

    • PHP_REQUIRE_CXX 用于指定这个扩展用到了C++;
    •         

    • PHP_ADD_INCLUDE 指定PHP扩展模块用到的头文件目录;
    •         

    • PHP_CHECK_LIBRARY 指定PHP扩展模块PHP_ADD_LIBRARY_WITH_PATH定义以及库连接错误信息等;
    •         

    • PHP_SUBST 用于说明这个扩展编译成动态链接库的形式;
    •         

    • PHP_NEW_EXTENSION 用于指定有哪些源文件应该被编译,文件和文件之间用空格隔开;
    •     

        

  •     

  • 这里指定PHP扩展模块的工作方式为 PHP_ARG_ENABLE ,需要修改config.m4文件为:

找到里面有类似几行:

修改成:

        

  • 除了修改 config.m4 外,还需要修改的文件有 getaddress.cphp_getaddress.h 两个文件,下面会说到该文件的修改。

4.3 创建configure文件

        

  • 源码修改:进入源代码根目录,使用工具 buildconf 创建 configure 文件,其命令如下:

        

  • 扩展修改:进入扩展目录,使用工具 phpize 创建 configure 文件,其目录如下:

4.4 创建Makefile文件

        

  • 上个步骤中创建了 configure 文件,记住,一般在类unix系统中, configure 文件是一个可执行文件,用来创建编译过程中所用到的make命令所需要的Makefile文件,其创建过程如下:

        

  • 注意,如果你写的扩展与apache有关,则需要关联apxs,产生apache的modules。

4.5 编译过程

        

  • 编译过程是一个调试过程,出现错误了需要检查 config.m4getaddress.cphp_getaddress.h 这几个文件是否编写正确,编译的过程十分简单,命令如下:

4.6 安装扩展模块

        

  • 安装扩展模块一般有两种安装,一种是直接:

        

  • 结果会安装到: /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/ 目录,然后在 php.ini 里面通过 extension_dir 将该目录设置为php的扩展目录,并在php.ini中打开这个扩展:

        

  • 另外一种是直接复制。一般经过编译过程这个步骤后,会在 getaddress 目录下生成一个目录: modules ,该目录下面有一个已经编译好的.so文件,如果是静态编译,可能是.a或.la;把该文件复制到一个目录下,比如: /usr/loca/php/ext/ ,然后直接调用函数 dl 来调用其 api。

 

4.7 运行测试

        

  • getaddress 目录下有一个 getaddress.php 文件专门用来测试你的扩展模块是否正确运行,该文件即可以作为 CGI 来运行又可以当作脚本执行,命令如下:

 

4.8 增添PHP扩展模块函数

        

  • 上述讲了这么多,这节才是最主要的。PHP扩展模块主要有三个方面的作用:    
              

    1. 增加PHP基础函数没有的功能或更加 OOP(Object Oriented Programming) 的思想供工程调用;
    2.         

    3. PHP的扩展一般是汇编、C/C++等编译性语言缩写,二进制运行消耗时间比解释性语言实现同样的功能少得多;
    4.         

    5. 由于PHP扩展一般是二进制的,所以一般来说不开源,很方便的保护了版权,能够进行商业运用。
    6.     

        

  •     

  • 默认的 getaddress.c 中, zend_function_entry 是导出函数列表, zend_module_entry 描述了模块的信息。
  •     

  • 编写代码应该注意:    
              

    1. 如果是C++开发,记住把getaddress.c的后缀改为cpp,并用extern "C"来把c相关代码包起来;
    2.     

        

 

5 Bugs

        

  • 在64位机器上和32位机器上会出现很大的差异,主要在QQWry.c文件;
  •     

  • 多个引用php函数会出现corp dump情况,具体原因还未查清;

 

6 实例代码

        

  • 注意,修复一处Bug:将

代替

 

7 总结

        

  • 由于作者对C指针运用不太熟练,所以在操作指针时,往往会出现corp dump,这方面有待加强;
  •     

  • 就PHP扩展来说,涵盖的面比较广,需要丰富的知识面做铺垫才能做好一个优秀的扩展。

留下评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据