php 與C/C++ 集成的方法有哪些?

  php和c/c++最常用的調用方式是通過tcp或http去調用,通過發送請求去調用c/c++編寫的cgi/fastcgi來實現,另外php還有一種直接執行外部應用程序的方式,這種方式會影響到系統安全,容易被攻擊者利用,所以使用的時候要謹慎處理好用戶輸入

  php執行外部二進位命令的函數有好幾個,比如exec和passthru,並且passthru函數能執行命令並且可以返回外部命令的輸出,所以本次就使用passthru來實現,php調用c/c++函數的目的就是處理複雜計算時提高計算效率,從而提高整體的系統性能,下面是一個簡單的測試案例
  首先編寫一個test.c源文件,處理很簡單就是對兩個整數進行加法運算,代碼如下:

```

#include

int main(int argc, char **argv) {

  //printf("參數數量:%d\n", argc-1);

  int a = atol(argv[1]);

  int b = atol(argv[2]);

  int sum = a + b;

  printf("%d\n", sum);

  return 0;

}

```

保存後,執行編譯:`gcc test.c -o test`編譯後會在當前目錄下生成test可執行文件,通過./test 5 12可以執行文件看到輸出17

  然後寫表單和php代碼,為了簡單,當前目錄就是web訪問根目錄,實際中要把C/C++項目放在web訪問目錄之外,在php中使用絕對路徑調用   **表單form.html代碼**:

``` html

php與c/c++交互案例

 

 

請輸入兩個整數:

   

+

 

```

 **php處理程序add.php代碼**:

``` php

header("Content-Type:text/html; charset=utf-8");

if(sset($_POST["a"]) && isset($_POST["b"]) && !empty($_POST["a"]) && !empty($_POST["b"])) {

$command = "./test ".$_POST["a"]." ".$_POST["b"];

$result = passthru($command);

print_r($result);

} else {

echo "輸入的內容不能為空!";

}

?>

```



答: 因為有PHP擴展開發經歷,目前也在開發PHP擴展,所以來介紹一下PHP擴展開發,也就是通過擴展的方式集成。

題主應該知道,PHP是通過C語言開發的,而開發PHP擴展也是通過C去實現的。

為什麼我們要通過擴展的方式去集成進我們的項目,因為擴展通過底層C實現後,速度要比原生PHP快很多,我舉個例子。

Yaf、Zend、Laravel等這幾種框架里,只有Yaf通過PHP擴展去實現的,也就是說是C所開發的,下面是簡單的對比

壓力測試: Zend屬於最差的,Yaf屬於最好,其次是Laravel

內存使用率:Yaf依舊是最好的

這也是擴展開發的好處,但是擴展開發有哪些風險呢,你在開發擴展的過程中,需要經過嚴格的內存泄漏測試,Yaf框架最初也被質疑過是否存在內存泄漏,但是在新浪、百度、360等眾多公司使用的過程中,已經證明了Yaf是不存在這個問題的,ok好像有點偏題了。

擴展是建議C++的,因為你不清楚你們公司的集群或者某台機器是否支持g++編譯,而c++能做的事情c一定可以實現的,所以都是C去開發。

至於通過擴展去實現PHP,你需要注意以下幾點:

  1. PHP版本,你們公司是5.2的話,你當然不能去拿5.5的去做開發編譯測試環境。

  2. gcc版本,gcc版本也是你在開發過程中需要注意的地方。

  3. 依賴庫,例如你的擴展需要依賴libpng或某個版本以上或以下,這些兼容性或者不兼容你都要羅列非常清楚。

  4. 內存,如果你的擴展存在內存泄漏,這就不是嚴不嚴重的問題,是能不能用的問題了,至少生產環境是不會考慮。

  5. PHP擴展開發的規範,比如返回值方式 例如RETURN_LONG;同時對於RESOURCE的管理。

  6. 你要對PHP源代碼了解,Zval容器,PHP的POST以及GET內部實現方式。

在一個PHP通過編譯打包好.so配置之後,你可以通過phpinfo看到你的擴展,

如圖,

這是我最近開發的一個爬蟲擴展。

大多坑都是你在c中所遇到的,比如sprintf需要慎用。

其他方式:

例如 通過exec執行shell,這種方法其實不僅限於你去執行c,還可以做很多事,但是不推薦。

題主如果不是在問c和php交互的話,應該就是以上這幾種了,一般都是擴展。

歡迎派友補充~



  php和c/c++最常用的調用方式是通過tcp或http去調用,通過發送請求去調用c/c++編寫的cgi/fastcgi來實現,另外php還有一種直接執行外部應用程序的方式,這種方式會影響到系統安全,容易被攻擊者利用,所以使用的時候要謹慎處理好用戶輸入

  php執行外部二進位命令的函數有好幾個,比如exec和passthru,並且passthru函數能執行命令並且可以返回外部命令的輸出,所以本次就使用passthru來實現,php調用c/c++函數的目的就是處理複雜計算時提高計算效率,從而提高整體的系統性能,下面是一個簡單的測試案例

  首先編寫一個test.c源文件,處理很簡單就是對兩個整數進行加法運算,代碼如下:

```

#include

int main(int argc, char **argv) {

//printf("參數數量:%d
", argc-1);

int a = atol(argv[1]);

int b = atol(argv[2]);

int sum = a + b;

printf("%d
", sum);

return 0;

}

```

保存後,執行編譯:`gcc test.c -o test`編譯後會在當前目錄下生成test可執行文件,通過./test 5 12可以執行文件看到輸出17

  然後寫表單和php代碼,為了簡單,當前目錄就是web訪問根目錄,實際中要把C/C++項目放在web訪問目錄之外,在php中使用絕對路徑調用

  **表單form.html代碼**:

``` html

php與c/c++交互案例

請輸入兩個整數:

+

```

 **php處理程序add.php代碼**:

``` php

header("Content-Type:text/html; charset=utf-8");

if(isset($_POST["a"]) && isset($_POST["b"]) && !empty($_POST["a"]) && !empty($_POST["b"])) {

$command = "./test ".$_POST["a"]." ".$_POST["b"];

$result = passthru($command);

print_r($result);

} else {

echo "輸入的內容不能為空!";

}

?>

```



推薦閱讀:

C++會過時嗎?如果會,大概可以估計幾年後會過時呢?
C++派生類的成員或友員只能通過派生類對象來訪問基類的受保護成員?
一個關於visual studio的問題?
protobuf 變長64位無符號整數 為什麼最多需要消耗10位元組而不是9位元組?
cocos2dx開發遊戲,如果可以使用C++做出來,是不是不用lua,全用C++做更好呢?

TAG:PHP | 編程語言 | 編程 | C | PHP學習 |