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
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(
0 => array("pipe", "r"), // stdin é um pipe a partir do qual o processo filho vai ler
1 => array("pipe", "w"), // stdout é um pipe a partir do qual o processo filho vai escrever
2 => 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(
0 => array("pty"),
1 => array("pty"),
2 => array("pty")
);
$process = proc_open("cvs -d:pserver:cvsread@cvs.php.net:/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.