Forum und email

proc_open

(PHP 4 >= 4.3.0, PHP 5)

proc_open — Executa um comando e abre ponteiros de arquivos para entrada/saída

Descrição

resource proc_open ( string $cmd , array $descriptorspec , array $pipes )

proc_open() é similar a popen() mas provê um controle muito maior sobre a execução do programa. cmd é o comando a ser executado pelo shell. descriptorspec é uma mariz indexada aonde a chave representa o número do descritor e o valor representa como o PHP irá passar o descritor para o processo filho. pipes será definido como uma matriz de ponteiros de arquivos que corresponde no PHP a qualquer pipe que foi criado. O valor de retorno é um recurso representando o processo, você deve libera-lo usando proc_close() quando você tiver terminado com ela.

<?php
$descriptorspec 
= array(
   
=> array("pipe""r"),  // stdin é um pipe a partir do qual o processo filho vai ler
   
=> array("pipe""w"),  // stdout é um pipe a partir do qual o processo filho vai escrever
   
=> array("file""/tmp/error-output.txt""a"// stderr é um arquivo que será escrito
);
$process proc_open("php"$descriptorspec$pipes);
if (
is_resource($process)) {
    
// $pipes parece com isso agora:
    // 0 => manipulador de escrita conectado com o stdin do processo filho
    // 1 => manipulador de leitura conectado com o stdout do processo filho
    // Qualquer saída de erro será adicionada em /tmp/error-output.txt

    
fwrite($pipes[0], "<?php echo \"Hello World!\"; ?>");
    
fclose($pipes[0]);

    while (!
feof($pipes[1])) {
        echo 
fgets($pipes[1], 1024);
    }
    
fclose($pipes[1]);
    
// É importante que você feche qualquer pipe antes de usar
    // proc_close para evitar um travamento
    
$return_value proc_close($process);

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

O PHP 5RC2 introduz suporte pty para sistemas com Unix98 ptys. Isto permite ao seu script interagir com aplicações que esperão estar conversando com um terminal. Um pty funciona como um pipe, mas é bi-direcional, então não é necessário especificar um modo de leitura/escrita. O exemplo abaixo mostra como usar um pty; note que você não precisa ter todos os descritores conversando com um pty. Note também que apenas um pty é criado, mesmo que o pty seja especificado 3 vezes. Em versões futuras do PHP, será possível fazer mais do que apenas ler e escrever para o pty.

<?php
// Cria um pseudo terminal para o processo filho
$descriptorspec = array(
  
=> array("pty"),
  
=> array("pty"),
  
=> array("pty")
);
$process proc_open("cvs -d:pserver:[email protected]:/repository login"$descriptorspec$pipes);
if (
is_resource($process)) {
   
// work with it here
}
?>

Os números de descritores em descriptorspec não saõ limitados a 0, 1 e 2 - você pode especificar qualquer número de descritor de arquivo válido e será passado para o processo filho. Isto permite ao seu script interagir com outros scripts que funcionam como "co-processos". Em particular, isto é útil para passar senhas para programas como PGP, GPG e openssl de uma maneira mais segura. É útil também para ler a informação de status provida por estes programas nos descritores de arquivos auxiliares.

Nota: Compatibilidade com o Windows: Descritores além do 2 (stderr) são disponibilizados para o Windows, mas desde que a arquitetura Windows não associa descritores de arquivos com os manipuladores de baixo nível, o processo filho não tem (ainda) meios de acessar estes manipuladores. Stdin, stdout e stderr funcionam como esperado.

Nota: Se você precisa de um pipe de processo uni-direcional, use a função popen() ao invés, já que ela é muito mais fácil de usar.

Veja também stream_select(), exec(), system(), passthru(), popen(), escapeshellcmd(), e o operador backtick.