PHP執行外部程式的方法

來源:互聯網
上載者:User
這篇文章主要介紹了PHP實現執行外部程式的方法,結合執行個體形式分析了php執行外部程式的常用函數相關提示與注意事項,需要的朋友可以參考下

具體如下:

在一些特殊情況下,會使用PHP調用外部程式執行,比如:調用shell命令、shell指令碼、可執行程式等等,今天在源碼中瞭解了一下PHP執行外部程式的方法,藉此機會順便整理一下。

在源碼中 exec.h檔案中,列出了可調用外部程式的幾個函數,藍色框裡的兩個函數只是輔助作用,本文只對其他幾個函數做介紹。

前提

1 PHP沒有運行在安全模式,關掉安全模式,即:safe_mode = off

2 禁用函數列表 disable_functions = exec, system, shell_exec,proc_open, popen, 如果禁用了,就關掉。

注意:執行外部程式是存在風險的,所以使用這些函數要在確保安全的情況下使用。

exec() 函數

原型:string exec ( string command [, array &output [, int &return_var]] )

描述:傳回值儲存最後的輸出結果,而所有輸出結果將會儲存到$output數組,$return_var用來儲存命令執行的狀態代碼(用來檢測成功或失敗)。

例子:

<?phpexec('whoami',$output, $status);var_dump($output);exit;

輸出結果:

array(1) { [0]=> string(7) "hedong"}

注意:

① 輸出結果會逐行追加到$output中,因此在調用exec之前需要unset($output),特別是迴圈調用的時候。

② 如果想通過exec調用外部程式後馬上繼續執行後續代碼,僅僅在命令裡加"&"是不夠的,此時exec依然會等待命令執行完畢;需要再將標準輸出做重新導向才可以,例如:exec("ls -al >/dev/null &", $output, $var);

shell_exec() 函數

原型:string shell_exec( string command)

描述:通過 shell 環境執行命令,並且將完整的輸出以字串的方式返回。

例子:

<?php$output = shell_exec('whoami');echo "$output"; // hedongexit;

注意:

當進程執行過程中發生錯誤,或者進程不產生輸出的情況下,都會返回 NULL, 所以,使用本函數無法通過傳回值檢測進程是否成功執行。 如果需要檢查進程執行的退出碼,請使用 exec() 函數。

system() 函數

原型:string system ( string command [, int &return_var] )

描述:執行給定的命令,返回最後的輸出結果;第二個參數是可選的,用來得到命令執行後的狀態代碼。

例子:

<?phpsystem("whoami", $status); // 直接輸出var_dump($status); // 成功時狀態代碼是 0exit;

輸出結果:hedong

passthru() 函數

原型:void passthru (string command [, int return_var])

描述:執行給定的命令,但不返回任何輸出結果,而是直接輸出到顯示裝置上;第二個參數可選,用來得到命令執行後的狀態代碼。

用途:當所執行的 Unix 命令輸出位元據, 並且需要直接傳送到瀏覽器的時候, 需要用此函數來替代 exec() 或 system() 函數

例子:

<?phppassthru("whoami", $status); // 直接輸出var_dump($status); // 成功時狀態代碼是 0exit;

輸出結果:hedong

popen() 函數

原型:resource popen ( string command, string mode )

描述:開啟一個指向進程的管道,該進程由派生給定的 command 命令執行而產生。 返回一個和 fopen() 所返回的相同的檔案指標,只不過它是單向的(只能用於讀或寫)並且必須用 pclose() 來關閉。此指標可以用於 fgets(),fgetss() 和 fwrite()。

例子:

$fd = popen("command", 'r');$ret = fgets($fd);

注意:只能開啟單向管道,不是'r'就是'w';並且需要使用pclose()來關閉。

proc_open() 函數

原型:resource proc_open ( string cmd, array descriptorspec, array &pipes [, string cwd [, array env [, array other_options]]] )

描述:與popen類似,但是可以提供雙向管道。

例子:

<?php/** * @author: hedong * @date 2017-04-04 */// 管道配置$descriptors = array(  0 => array("pipe", "r"),  1 => array("pipe", "w"));$process = proc_open("php", $descriptors, $pipes);if (is_resource($process)) {  fwrite($pipes[0], "<?php\n");  fwrite($pipes[0], " \$rand = rand(1,2);\n");  fwrite($pipes[0], " if (\$rand == 1) {\n");  fwrite($pipes[0], "  echo \"Hello, World!\n\";\n");  fwrite($pipes[0], " } else {");  fwrite($pipes[0], "  echo \"Goodbye, World!\n\";\n");  fwrite($pipes[0], " }");  fwrite($pipes[0], "?>");  fclose($pipes[0]);  $output = "";  while (!feof($pipes[1])) {    $output .= fgets($pipes[1]);  }  $output = strtoupper($output);  echo $output; fclose($pipes[1]);  proc_close($process);}

輸出結果:

GOODBYE, WORLD!

注意:

① 後面需要使用proc_close()關閉資源,並且如果是pipe類型,需要用pclose()關閉控制代碼。
② proc_open開啟的程式作為php的子進程,php退出後該子進程也會退出。

總結:

exec函數將輸出結果儲存在第二個參數上;

shell_exec函數沒有參數中接收傳回值,而且沒有執行成功的狀態代碼;

system函數將執行的結果直接輸出;passthru函數同system函數,不同之處是適合處理輸出位元據;

popen函數會fork一個子進程,返迴文件指標

proc_open函數同popen,但可提供雙向通道


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.