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的庫文件里的方法了

  ?>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM