美文网首页我爱编程
PHP的C/C++扩展(一)

PHP的C/C++扩展(一)

作者: 程序员_张雪峰 | 来源:发表于2016-07-31 21:51 被阅读557次

    因为个性化推荐系统的开发,是架构组与策略组的跨小团队合作,所以策略方不愿意公开自己的代码,所以就只能采用我们提供系统功能,对方提供策略部分.so文件来实现(策略团队以C/C++作为主要语言)。

    一、ext_skel 脚本

    PHP 扩展由几个文件组成,这些文件对所有扩展来说都是通用的。不同扩展之间,这些文件的很多细节是相似的,只是要费力去复制每个文件的内容。幸运的是,有脚本可以做所有的初始化工作,名为 ext_skel,自 PHP 4.0 起与其一起分发。

    不带参数运行 ext_skel 在 PHP 5.6.24(最新正式版本) 中会产生以下输出:

    ./ext_skel --extname=module [--proto=file] [--stubs=file] [--xml[=file]]
               [--skel=dir] [--full-xml] [--no-help]
    
     --extname=module   module is the name of your extension
      --proto=file       file contains prototypes of functions to create
      --stubs=file       generate only function stubs in file
      --xml              generate xml documentation to be added to phpdoc-svn
      --skel=dir         path to the skeleton directory
      --full-xml         generate xml documentation for a self-contained extension
                         (not yet implemented)
      --no-help          don't try to be nice and create comments in the code
                         and helper functions to test if the module compiled
    

    通常来说,开发一个新扩展时,仅需关注的参数是 --extname 和 --no-help。除非已经熟悉扩展的结构,不要想去使用 --no-help; 指定此参数会造成 ext_skel 在生成文件里省略很多有用的注释。剩下的 --extname 会将扩展的名称传给 ext_skel。"name" 是一个全为小写字母的标识符,仅包含字母和下划线,在 PHP 发行包的 ext/ 文件夹下是唯一的。*** 官网说了:其它参数不用明白,也不要尝试。 ***

    执行创建edutest1

     ✘ zhangxuefeng@zhangxuefengdeMac-mini  ~/Developer/php-5.6.24/ext  ./ext_skel --extname=edutest1
    Creating directory edutest1
    Creating basic files: config.m4 config.w32 .gitignore edutest1.c php_edutest1.h CREDITS EXPERIMENTAL tests/001.phpt edutest1.php [done].
    
    To use your new extension, you will have to execute the following steps:
    
    1.  $ cd ..
    2.  $ vi ext/edutest1/config.m4
    3.  $ ./buildconf
    4.  $ ./configure --[with|enable]-edutest1
    5.  $ make
    6.  $ ./sapi/cli/php -f ext/edutest1/edutest1.php
    7.  $ vi ext/edutest1/edutest1.c
    8.  $ make
    
    Repeat steps 3-6 until you are satisfied with ext/edutest1/config.m4 and
    step 6 confirms that your module is compiled into PHP. Then, start writing
    code and repeat the last two steps as often as necessary.
    

    二、与 UNIX 构建系统交互: config.m4

    扩展的 config.m4 文件告诉 UNIX 构建系统哪些扩展 configure 选项是支持的,你需要哪些扩展库,以及哪些源文件要编译成它的一部分。

    autoconf 语法简介

    config.m4 文件使用 GNU autoconf 语法编写。简而言之,就是用强大的宏语言增强的 shell 脚本。注释用字符串 dnl 分隔,字符串则放在左右方括号中间(例如,[ 和 ])。字符串可按需要多次嵌套引用。

    根据需要修改config.m4

    1. 切换到ext/edutest1/目录。
    2. vi config.m4
    3. 将下面的第一、三行取消注释,并删掉第二行:
    16 dnl PHP_ARG_ENABLE(edutest1, whether to enable edutest1 support,
     17 dnl Make sure that the comment is aligned:
     18 dnl [  --enable-edutest1           Enable edutest1 support])
    
    修改为:
    
    16 PHP_ARG_ENABLE(edutest1, whether to enable edutest1 support,
     17     [  --enable-edutest1           Enable edutest1 support])
    
    1. PHP_SUBST一行的注释打开:
    19 if test "$PHP_EDUTEST1" != "no"; then
    ……
    59   PHP_SUBST(EDUTEST1_SHARED_LIBADD)
    60
    61   PHP_NEW_EXTENSION(edutest1, edutest1.c, $ext_shared)
    62 fi
    

    简要说明:

    宏PHP_ARG_ENABLE,含有三个参数:

    第一个参数,extest1./configure建立了名为enable-edutest1的选项
    第二个参数将会在./configure命令处理到该扩展的配置文件时,显示该参数的内容
    第三个参数是./configure命令的帮助,在使用./configure --help的时候显示

    宏PHP_NEW_EXTENSION

    该宏声明了扩展的模块和必须要编译作为扩展一部分的源码文件。如果需要多个源文件,则使用空格分隔,第三个参数$ext_shared与调用PHP_SUBST(EDUTEST1_SHARED_LIBADD)有关。

    三、phpize、配置、编译

    因为我的Mac上已经自带了PHP的环境,就不采取全套PHP源码编译的方法了。使用命令行工具phpize对扩展进行编译。

    phpize 命令是用来准备 PHP 扩展库的编译环境的工具。如果系统中没有 phpize 命令并且使用了预编译的包(例如 RPM),那要安装 PHP 包相应的开发版本,此版本通常包含了 phpize 命令以及相应的用于编译 PHP 及其扩展库的头文件。使用 phpize --help 命令可以显示此命令用法。

    使用root权限执行phpize:

     zhangxuefeng@zhangxuefengdeMac-mini  ~/Developer/php-5.6.24/ext/edutest1  sudo /usr/bin/phpize
    Password:
    Configuring for:
    PHP Api Version:         20121113
    Zend Module Api No:      20121212
    Zend Extension Api No:   220121212
    

    configure,需要使用php-config工具:

    php-config 是一个简单的命令行脚本用于获取所安装的 PHP 配置的信息。在编译扩展时,如果安装有多个 PHP 版本,可以在配置时用 --with-php-config 选项来指定使用哪一个版本编译,该选项指定了相对应的 php-config 脚本的路径。

     ✘ zhangxuefeng@zhangxuefengdeMac-mini  ~/Developer/php-5.6.24/ext/edutest1  sudo ./configure --enable-edutest1 --with-php-config=/usr/bin/php-config
    checking for grep that handles long lines and -e... /usr/bin/grep
    checking for egrep... /usr/bin/grep -E
    checking for a sed that does not truncate output... /usr/bin/sed
    checking for cc... cc
    ……
    

    Make 编译:

     zhangxuefeng@zhangxuefengdeMac-mini  ~/Developer/php-5.6.24/ext/edutest1  sudo make
    Password:
    /bin/sh /Users/zhangxuefeng/Developer/php-5.6.24/ext/edutest1/libtool --mode=compile cc  -I. -I/Users/zhangxuefeng/Developer/php-5.6.24/ext/edutest1 -DPHP_ATOM_INC -I/Users/zhangxuefeng/Developer/php-5.6.24/ext/edutest1/include -I/Users/zhangxuefeng/Developer/php-5.6.24/ext/edutest1/main -I/Users/zhangxuefeng/Developer/php-5.6.24/ext/edutest1 -I/usr/include/php -I/usr/include/php/main -I/usr/include/php/TSRM -I/usr/include/php/Zend -I/usr/include/php/ext -I/usr/include/php/ext/date/lib  -DHAVE_CONFIG_H  -g -O2   -c /Users/zhangxuefeng/Developer/php-5.6.24/ext/edutest1/edutest1.c -o edutest1.lo
    mkdir .libs
    ……
    ……
    ……
    Build complete.
    Don't forget to run 'make test'.
    

    Make Install:

     zhangxuefeng@zhangxuefengdeMac-mini  ~/Developer/php-5.6.24/ext/edutest1  sudo make install
    Installing shared extensions:     /usr/lib/php/extensions/no-debug-non-zts-20121212/
    

    添加完整路径到php.ini中:

     zhangxuefeng@zhangxuefengdeMac-mini sudo vim /etc/php.ini
    ……
    899 extension=/usr/lib/php/extensions/no-debug-non-zts-20121212/edutest1.so
    ……
    

    四、重启HTTP服务:

    phpinfo截图.png

    成功!

    相关文章

      网友评论

        本文标题:PHP的C/C++扩展(一)

        本文链接:https://www.haomeiwen.com/subject/xsfxsttx.html