Pregunta
Sé que PHP se utiliza generalmente para el desarrollo web, donde es ninguna entrada estándar, pero PHP pretende ser utilizable como un lenguaje de programación de propósito general, si sigue Es moderno basado en la web convenciones. Yo sé que las impresiones de PHP para stdout
(o como se quiera llamarlo) con print
y echo
, que es bastante simple, pero me pregunto cómo un script PHP podría tomar la entrada de stdin
(específicamente con fgetc()
, pero cualquier función de entrada es buena), o es esto posible?
Solución
Es posible leer el stdin
mediante la creación de un identificador de archivo a php://stdin
y luego leer de él con fgets()
para una línea, por ejemplo (o, como ya se ha dicho, fgetc()
para un solo carácter):
<?php
$f = fopen( 'php://stdin', 'r' );
while( $line = fgets( $f ) ) {
echo $line;
}
fclose( $f );
?>
Otros consejos
Lectura de STDIN es forma recomendada
<?php
while (FALSE !== ($line = fgets(STDIN))) {
echo $line;
}
?>
Para evitar tener que perder el tiempo con filehandles, utilice file_get_contents()
y php://stdin
:
$ echo 'Hello, World!' | php -r 'echo file_get_contents("php://stdin");'
Hello, World!
(Si está leyendo una verdadera gran cantidad de datos de stdin
es posible que desee utilizar el enfoque de gestor de archivo, pero esto debe ser bueno para muchos megabytes).
Un método simple es
$var = trim(fgets(STDIN));
Puede utilizar fopen()
en php://stdin
:
$f = fopen('php://stdin', 'r');
Coge todo de una sola vez:
$contents = file_get_contents("php://stdin");
echo $contents;
IIRC, también se puede utilizar lo siguiente:
$in = fopen(STDIN, "r");
$out = fopen(STDOUT, "w");
Técnicamente lo mismo, pero una sintaxis-sabia poco más limpio.
Esto también funciona:
$data = stream_get_contents(STDIN);
Al utilizar fgets, puede bloquear en scripts bash, si el stdin
no se establece o vacío, incluyendo durante el uso de la @
php operador de control de error .
#!/usr/bin/php
<?php
$pipe = @trim(fgets(STDIN));
// Script was called with an empty stdin
// Fail to continue, php warning
Este comportamiento se puede evitar mediante el establecimiento de stream_set_blocking
en la cabecera 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 ejemplo, a ser llamado como sigue:
echo "Hello world" | ./myPHPscript
// Output "Hello world!"
./myPHPscript
// Output "!"