php 增加扩展so库

 项目需求:

  之前做项目遇到了一个需求:  需要对接c/c++封装的so库,需要用php调用so库里面的方法。

 需求设想:

  接触之初,脑海中脑补了下这个需求应该怎么整:  没搞过啊,是不是把这个so库文件当做类,然后引用这个类再执行类里的方法。(哈哈,很单纯无知的想法)

  拿到so库后,查看了下,这封装过了的,咋引用~~。 查找一番后确定了大致的实施方法: 增加php底层扩展方法,在扩展中引入库进行编译,编译成功生成php的引用扩展库,即可直接调用扩展库方法。

 实施测试阶段:

  因为是引用c++的扩展库,库里引用和opencv的一些扩展库,里面需要很多配套的扩展,一个萝卜一个坑,慢慢得趟出了很多坑,也获得了很多萝卜。

  萝卜1: 编译中报出各种错,不是缺少这个扩展,就是缺少那个扩展,就得针对于各种缺少的各种安装,此过程中了解了很多扩展库的作用。

  萝卜2: 系统性得了解了巩固了linux的各种命令,重温了下C语言的语法与so库的封装。

  实施阶段:

  因为是需要用到php的源码增加扩展,先现在一份和当前php环境版本一致的源码。下载地址: http://php.net/downloads.php

  将so库的存放路径写入配置中保存(各个配置的环境路径也许会有不同)    打开 cd /etc/ld.so.conf.d/   vim local.conf   将so库存放路径/usr/local/lib写入保存

  解压源码包(路径没要求) 打开解压后的文件夹里的 ext文件夹,里面储存的是php自带的一些扩展目录,我们所要做的就是在里面再加一个我们需要的扩展。

  开始创建一个模块test:  执行命令:  sudo ./ext_skel --extname=test

  执行完会生成一个test的模块文件夹,打开test    cd test

  需要修改一些文件  给需要修改的文件权限  sudo chmod 777 config.m4  php_test.h  test.c

  1> 先修改 php_test.h  在声明方法下 增加一个你自己定义的调取so库的方法 如增加 test_add 方法:

  PHP_FUNCTION(confirm_suone_compiled);   /* For testing, remove later. */

  PHP_FUNCTION(test_add); //声明此函数 (后面test.c中将用到)

  2> 修改config.m4:

  PHP_ARG_WITH(test, for test support,    //放开此两行的注释   __WITH 是引用的外部库文件又引用了其他链接库  如果是引用单一的一个so文件,即放开 __ENABLE那两行

   [  --with-test            Include test support]) 

  

  在底部引入扩展目录及文件,例如需添加的so库名称为 gettime.so  

  PHP_ADD_LIBRARY_WITH_PATH(gettime,/usr/local/lib,TEST_SHARED_LIBADD)

  PHP_ADD_LIBRARY_WITH_PATH(opencv_core,/usr/local/lib, TEST_SHARED_LIBADD)  //引入一个opencv的链接库为例 此库都放在 /usr/local/lib 文件夹下

  PHP_SUBST(TEST_SHARED_LIBADD)    //加入此句表示此库为共享库

  PHP_NEW_EXTENSION(test, test.c, $ext_shared)

  3> 修改 test.c文件 (主函数文件)

  const zend_function_entry test_functions[] = {

  PHP_FE(confirm_test_compiled,  NULL)           /* For testing, remove later. */

  PHP_FE(test_add,NULL)     //加入此方法

  {NULL,NULL,NULL}

  //      PHP_FE_END      /* Must be the last line in suone_functions[] */

  };

  在文件底部,写函数调用方法 

  PHP_FUNCTION(test_add){ //test_add 是上面申明的方法名

      char *name=NULL; //定义类型

      long len;

      long uid;

      If(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &name,&len ,&uid) == FAILURE) {

          return;

      }

      char *data = Gettime(name,uid); //直接请求外部库gettime.so的 Gettime函数,传递参数,获取值

      RETURN_STRINGL(data,strlen(data)+1,1); //返回结果值

  }

  每个库的请求方法和参数结合不相同,具体根据外部库所需要的参数为准

  4> 文件修改完毕,现在执行编译命令,生成php可直接执行的底层库

  sudo phpize

  sudo ./configure  --with-php-config=/usr/bin/php-config --with-test

  sudo make  test   (先执行test 如果此步骤返回success,即可正常执行下面的安装,如果报错,先处理至没错)

  sudo make install  (安装完之后会生成一个新的库test.so 文件,将此文件复制到php的扩展库目录中  /usr/local/lib)

  将 test.so 写入到php.ini的配置中  Extension=test.so  如果在之前的配置中引入了整个库文件目录,就不需要单独引入此文件

  重启php服务

  测试结果

  新建一个test.php 文件  

  <?php

    print_r(test_add("so库测试",1));   //test_add为扩展主方法里所写入的方法名,即可链接调用gettime.so的库文件里的方法了

  ?>

猜你喜欢

转载自www.cnblogs.com/bugchao/p/9051859.html