2014-01-22 85 views
2

我是新來的PHP。當我在讀使用proc_open()來從其官方文檔的php執行命令,我發現這個例子:爲什麼我們沒有關閉指向文件的描述符?

<?php 
$descriptorspec = array(
    0 => array("pipe", "r"), // stdin is a pipe that the child will read from 
    1 => array("pipe", "w"), // stdout is a pipe that the child will write to 
    2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to 
); 

$cwd = '/tmp'; 
$env = array('some_option' => 'aeiou'); 

$process = proc_open('php', $descriptorspec, $pipes, $cwd, $env); 

if (is_resource($process)) { 
    // $pipes now looks like this: 
    // 0 => writeable handle connected to child stdin 
    // 1 => readable handle connected to child stdout 
    // Any error output will be appended to /tmp/error-output.txt 

    fwrite($pipes[0], '<?php print_r($_ENV); ?>'); 
    fclose($pipes[0]); 

    echo stream_get_contents($pipes[1]); 
    fclose($pipes[1]); 

    // It is important that you close any pipes before calling 
    // proc_close in order to avoid a deadlock 
    $return_value = proc_close($process); 

    echo "command returned $return_value\n"; 
} 
?> 

爲什麼我們還沒有關閉使用第三(管[2])文件描述符fclose()還是會自動關閉?

我試圖關閉它,但隨後它會發出警告:

PHP Notice: Undefined offset: 1 in test.php on line 121 
PHP Warning: fclose() expects parameter 1 to be resource, null given in test.php on line 121 
+0

如果您使用的文件路徑和'file'類型描述符,'proc_open()'將處理該文件的所有操作,這樣你就不會回來,你可以寫或讀的資源。 – piotrekkr

回答

1

有趣的問題。您只能關閉std *管道。當您使用標準管道開通:

$descriptorspec = array(
     0 => array("pipe", "r"), // stdin is a pipe that the child will read from 
     1 => array("file", 'dump.log', "w"), // file instead stdout 
     2 => array("pipe", "a") 
    ); 
$cwd = '/tmp'; 
$env = array('some_option' => 'aeiou'); 

$process = proc_open('php', $descriptorspec, $pipes, $cwd, $env); 

print_r($pipes); 

你會看到類似這樣的:

Array 
(
    [0] => Resource id #5 
    [2] => Resource id #6 
) 

所以$管[1]將不可用。

基於php源代碼,它看起來只有「管道」正在下降到$ pipes數組。

對於管道:PHP是用於上C.「管道」呼叫由於管描述符的進程之間共享的,並且如果沒有進程正在使用的管,操作系統只能在這種情況下,關閉配管。 「在技術說明中,如果管道的不必要的末端沒有明確關閉,EOF將永遠不會返回。」 - http://www.tldp.org/LDP/lpg/node11.html

+0

我想問,如果我們使用「fopen」打開一個文件,然後我們使用「fclose」關閉它,但在這種情況下,我們也打開一個文件寫入,爲什麼我們不關閉它,或者PHP自動關閉它?如果自動出現任何特殊原因,爲什麼不自動關閉其他描述符,出於安全原因或其他原因? – sdream

+0

是的,php會自動關閉「無管道」資源。關於管道 - 我已經更新了答案。 – Alexander

相關問題