有些時後在 PHP 裡難免會碰到需要外部程式的狀況;使用 system / exec 與重導 (<, >, |) 雖然很方便,不過又會有增加 I/O 的問題。在系統繁忙,要考慮 I/O 的情況下,使用 pipe function (popen, pclose, proc_open, …) 會比較恰當。這些函式能夠以 pipe 直接與其它程式溝通,避過了在 shell 處理重導的問題 (file lock & dead lock, I/O)。其中 popen 有著只能 r 或 w 的限制,proc_open 則可以同時取代 in, out, err。
resource proc_open ( string $cmd , array $descriptorspec , array &$pipes [, string $cwd [, array $env [, array $other_options ]]] )
- $cmd : 執行的程式名稱,可以帶參數,例如 /bin/ls –color
- $descriptorspec : 指定 in, out, err 三個 pipe 如何處理
- &$pipes : 傳回對應至 $descriptorspec 所指定的幾個 pipe, 成員都是 resource, 兩者的 key 會相等
取自 PHP 官網,的 proc_open 範例如下:
<?php
array("pipe", "r"), // stdin 為 pipe
1 => array("pipe", "w"), // stdout 為 pipe
2 => array("file", "/tmp/error-output.txt", "a") // 將 stderr 導到 /tmp/error-output.txt, append
);
$cwd = '/tmp';
$env = array('some_option' => 'aeiou');
$process = proc_open('php', $descriptorspec, $pipes, $cwd, $env);
if (is_resource($process)) {
// $pipes 的元素是
// $pipes[0] : 可寫入的 stream, 對應到子行程的 stdin
// $pipes[1] : 可讀取的 stream, 對應到子行程的 stdout
fwrite($pipes[0], '');
fclose($pipes[0]);
// stdout 要透過 stream_get_contents 讀取, 因為 $pipes[1] 是 stream, 不是 file resource
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
// 要先 fclose($pipes) 才能 proce_close($process)
$return_value = proc_close($process);
echo "command returned $return_valuen";
}
?>
No Comments Yet