实战:用C写php扩展(一)

    技术2022-05-19  19

    1、  前言

    首先,确保你的机器安装了apachephp假设apache的安装目录为/usr/local/apache2,php的安装目录为/usr/local/php

     

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

     

    2、  实战

    我们要写一个php扩展:myExt

    cd /home/sunlylorn/php/ext ext_skel --extname=myExt cd myExt vi config.m4

    先来看一下一个默认的config.m4文件,如下所示:

    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

    //修改如下三行: 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 前缀的都是注释,注释是不被解析的。

    //当然你也可以修改如下三行: 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 的目录一样),后者正好相反。不过,不管你使用哪一个指令,你都应该注释掉另外一个。

    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的文件,该文件是自动生成的。我们先来看一下该文件中的内容:

    <?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()函数了


    最新回复(0)