array ( 0 => 'index.php', 1 => 'PHP Manual', ), 'head' => array ( 0 => 'UTF-8', 1 => 'pt_BR', ), 'this' => array ( 0 => 'function.proc-open.php', 1 => 'proc_open', ), 'up' => array ( 0 => 'ref.exec.php', 1 => 'Funções para Execução de programas', ), 'prev' => array ( 0 => 'function.proc-nice.php', 1 => 'proc_nice', ), 'next' => array ( 0 => 'function.proc-terminate.php', 1 => 'proc_terminate', ), 'alternatives' => array ( ), 'source' => array ( 'lang' => 'pt_BR', 'path' => 'reference/exec/functions/proc-open.xml', ), ); $setup["toc"] = $TOC; $setup["toc_deprecated"] = $TOC_DEPRECATED; $setup["parents"] = $PARENTS; manual_setup($setup); ?>
(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)
proc_open — Executa um comando e abre ponteiros de arquivo para entrada/saída
$command
,$descriptor_spec
,&$pipes
,$cwd
= null
,$env_vars
= null
,$options
= null
proc_open() é similar a popen() mas fornece um grau de controle muito maior sobre a execução do programa.
command
A linha de comando a executar, como uma string. Caracteres especiais precisam ser escapados adequadamente, e o uso de aspas deve ser apropriadamente aplicado.
Nota: No Windows, a menos que
bypass_shell
esteja definido paratrue
no parâmetrooptions
, o comando emcommand
é passado para cmd.exe (na verdade,%ComSpec%
) com a opção/c
como uma string sem aspas (isto é, exatamente como fornecido a proc_open()). Isto pode fazer com que cmd.exe remova as aspas que envolvem o comando emcommand
(para detalhes, consulte a documentação do cmd.exe), resultando em comportamento inesperado e potencialmente perigoso, porque as mensagens de erro de cmd.exe podem conter (partes dos) comandos passados emcommand
(veja exemplo abaixo).
A partir do PHP 7.4.0, command
pode ser passado como um array de parâmetros de comandos.
Neste caso, o processo será aberto diretamente (sem passar por um "shell")
e o PHP irá gerenciar qualquer escape de argumentos se necessário.
Nota:
No Windows, o escape de argumentos dos elementos do array assume que a análise de linha de comando é compatível com a análise dos argumentos de linha de comando feita pelas bibliotecas em tempo de execução do VC.
descriptor_spec
Um array indexado onte a chave representa o número descritor e o valor representa como o PHP irá passar esse descritor ao processo filho. 0 é stdin, 1 é stdout e 2 é stderr.
Cada elemento pode ser:
pipe
(o segundo
elemento pode ser r
para passar a ponta de leitura do tubo
ao processo, ou w
para passar a ponta de escrita) e
file
(o segundo elemento é um nome de arquivo).
Observe que qualquer outro tipo diferente de w
é tratado como r
.
STDIN
).
O número do descritor de arquivo não é limitado a 0, 1 e 2 - pode-se especificar qualquer número válido de descritor de arquivo e ele será passado ao processo filho. Isto permite que o script consiga operar com outros scripts que são executados como "co-processos". Em particular, isto é útil para passar senhas a programas como PGP, GPG e openssl de uma forma mais segura. Também é útil para ler informações de estado de decritores de arquivos auxiliares fornecidas por estes programas.
pipes
Será definido para um array indexado de ponteiros de arquivos que corresponde à ponta do PHP de qualquer tubo que seja criado.
cwd
O diretório de trabalho inicial para o comando. Precisa ser um
caminho de diretório absoluto, ou null
se for desejado usar o valor padrão (o diretório de trabalho do
processo PHP atual)
env_vars
Um array com as variáveis de ambiente para o comando que será
executado, ou null
para usar o mesmo ambiente do processo PHP atual
options
Permite especificar opções adicionais. As opções atualmente suportadas incluem:
suppress_errors
(somente Windows): suprime erros
gerados por esta função quando definida para true
bypass_shell
(somente Windows): ignora o "shell"
cmd.exe
quando definida para true
blocking_pipes
(somente Windows): força
tubos no modo de bloqueio quando definida para true
create_process_group
(somente Windows): permite ao
processo filho lidar com eventos CTRL
quando definida para true
create_new_console
(somente Windows): o novo processo
terá um novo console, ao invés de herdar o console do processo pai
Retorna um recurso representando o processo, que deve ser liberado usando
proc_close() quando seu uso tiver sido finalizado. Em caso de falha
retorna false
.
Versão | Descrição |
---|---|
7.4.4 |
Adicionada a opção create_new_console ao parâmetro
options .
|
7.4.0 |
proc_open() agora aceita um array
para o parâmetro command .
|
7.4.0 |
Adicionada a opção create_process_group ao parâmetro
options .
|
Exemplo #1 Um exemplo de proc_open()
<?php
$descriptorspec = array(
0 => array("pipe", "r"), // stdin é um tubo de onde o processo filho irá ler
1 => array("pipe", "w"), // stdout é um tubo no qual o processo filho irá escrever
2 => array("file", "/tmp/error-output.txt", "a") // stderr é um arquivo que será escrito
);
$cwd = '/tmp';
$env = array('some_option' => 'aeiou');
$process = proc_open('php', $descriptorspec, $pipes, $cwd, $env);
if (is_resource($process)) {
// $pipes agora será parecido com:
// 0 => manipulador que pode ser escrito, conectado ao stdin filho
// 1 => manipulador que pode ser lido, conectado ao stdout filho
// Qualquer saída de erro será anexaa ao /tmp/error-output.txt
fwrite($pipes[0], '<?php print_r($_ENV); ?>');
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
// É importante fechar todos os tubos antes de chamar
// proc_close para evitar o beco sem saída
$return_value = proc_close($process);
echo "comando retornou $return_value\n";
}
?>
O exemplo acima produzirá algo semelhante a:
Array ( [some_option] => aeiou [PWD] => /tmp [SHLVL] => 1 [_] => /usr/local/bin/php ) comando retornou 0
Exemplo #2 Peculiaridade de proc_open() no Windows
Embora seja esperado que o programa a seguir pesquise o arquivo
filename.txt pelo texto search
e
mostre os resultados, ele se comporta de maneira bastante diferente.
<?php
$descriptorspec = [STDIN, STDOUT, STDOUT];
$cmd = '"findstr" "search" "filename.txt"';
$proc = proc_open($cmd, $descriptorspec, $pipes);
proc_close($proc);
?>
O exemplo acima produzirá:
'findstr" "search" "filename.txt' is not recognized as an internal or external command, operable program or batch file.
Para contornar este comportamento, normalmente é suficiente envolver
command
com aspas adicionais:
$cmd = '""findstr" "search" "filename.txt""';
Nota:
Compatibilidade com Windows: Descritores além de 2 (stderr) estão disponíveis para o processo filho como manipuladores que podem ser herdados, mas como a arquitetura Windows não associa números de descritores de arquivos a manipuladores de baixo nível, o processo filho não tem (ainda) meios de acessar esses manipuladores. Stdin, stdout e stderr funcionam conforme esperado.
Nota:
Se for necessário somente um tubo de processo unidirecional (mão única), utilize a função popen(), pois é muito mais fácil de usar.