How can I check if stdin exists in PHP ( php-cgi )?

Regarding your specific problem of hanging when there is no input: php stream reads are blocking operations by default. You can change that behavior with stream_set_blocking(). Like so:

$fh = fopen('php://stdin', 'r');
stream_set_blocking($fh, false);
$stdin = fgets($fh);
echo "stdin: '$stdin'";  // immediately returns "stdin: ''"

Note that this solution does not work with that magic file handle STDIN.


You can use the select function such as:

$stdin = '';
$fh = fopen('php://stdin', 'r');
$read  = array($fh);
$write = NULL;
$except = NULL;
if ( stream_select( $read, $write, $except, 0 ) === 1 ) {
    while ($line = fgets( $fh )) {
            $stdin .= $line;
    }
}
fclose($fh);

stream_get_meta_data helped me :)

And as mentioned in the previous answer by Seth Battin stream_set_blocking($fh, false); works very well 👍

The next code reads data from the command line if provided and skips when it's not.

For example: echo "x" | php render.php and php render.php

In the first case, I provide some data from another stream (I really need to see the changed files from git, something like git status | php render.php.

Here is an example of my solution which works:

$input = [];

$fp = fopen('php://stdin', 'r+');
$info = stream_get_meta_data($fp);

if (!$info['seekable'] && $fp) {
    while (false !== ($line = fgets($fp))) {
        $input[] = trim($line);
    }
    fclose($fp);
}

Tags:

Php

Shell

Stdin