Pergunta
Eu sei PHP é normalmente usado para desenvolvimento web, onde há é nenhum entrada padrão, mas reivindicações de PHP para ser usado como uma linguagem de scripts de propósito geral, se você segui-lo é funk baseada em web convenções. Eu sei que o PHP imprime stdout
(ou o que você quiser chamá-lo) com print
e echo
, o que é suficiente simples, mas eu estou querendo saber como um script PHP pode obter a entrada de stdin
(especificamente com fgetc()
, mas qualquer função de entrada é bom), ou isso é mesmo possível?
Solução
É possível ler o stdin
criando um identificador de arquivo para php://stdin
e, em seguida, lê-lo com fgets()
para uma linha, por exemplo (ou, como já foi dito, fgetc()
para um único caractere):
<?php
$f = fopen( 'php://stdin', 'r' );
while( $line = fgets( $f ) ) {
echo $line;
}
fclose( $f );
?>
Outras dicas
Leitura de STDIN é maneira recomendada
<?php
while (FALSE !== ($line = fgets(STDIN))) {
echo $line;
}
?>
Para evitar ter que mexer com filehandles, uso file_get_contents()
e php://stdin
:
$ echo 'Hello, World!' | php -r 'echo file_get_contents("php://stdin");'
Hello, World!
(Se você está lendo um verdadeiramente enorme quantidade de dados de stdin
você pode querer usar a abordagem filehandle, mas isso deve ser bom para muitos megabytes).
Um método simples é
$var = trim(fgets(STDIN));
Você pode usar fopen()
em php://stdin
:
$f = fopen('php://stdin', 'r');
Grab tudo em um só tiro:
$contents = file_get_contents("php://stdin");
echo $contents;
IIRC, você também pode usar o seguinte:
$in = fopen(STDIN, "r");
$out = fopen(STDOUT, "w");
Tecnicamente o mesmo, mas um pouco mais limpo sintaxe-wise.
Isso também funciona:
$data = stream_get_contents(STDIN);
Ao usar fgets, pode bloquear em bash scripts, se o stdin
não está definido ou vazio, inclusive durante o uso do @
php operador de controle de erro .
#!/usr/bin/php
<?php
$pipe = @trim(fgets(STDIN));
// Script was called with an empty stdin
// Fail to continue, php warning
Este comportamento pode ser evitado por definição stream_set_blocking
no cabeçalho do php:
#!/usr/bin/php
<?php
stream_set_blocking(STDIN, 0);
$pipe = @trim(fgets(STDIN));
// Script was called with an empty stdin
// No errors or warnings, continue
echo $pipe . "!";
Como exemplo, para ser chamado como segue:
echo "Hello world" | ./myPHPscript
// Output "Hello world!"
./myPHPscript
// Output "!"