Gustavo Straube
Gustavo Straube

Reputation: 3861

How to check if bash input is being redirect to PHP script?

I'm writing a PHP script and I would like to be able to optionally use a file as the script input. This way:

$ php script.php < file.txt

I'm, actually, able to do that using file_get_contents:

$data = file_get_contents('php://stdin');

However, if I don't pass a file to the input, the scripts hangs indefinetelly, waiting for an input.

I tried the following, but it didn't work:

$data = '';
$in = fopen('php://stdin', 'r');
do {
    $bytes = fread($in, 4096);
    // Maybe the input will be empty here?! But no, it's not :(
    if (empty($bytes)) {
        break;
    }
    $data .= $bytes;
} while (!feof($in));

The script waits for fread to return a value, but it never returns. I guess it waits for some input the same way file_get_contents does.

Another attempt was made by replacing the do { ... } while loop by a while { ... }, checking for the EOF before than trying to read the input. But that also didn't work.

Any ideas on how can I achieve that?

Upvotes: 2

Views: 142

Answers (1)

Alex Howansky
Alex Howansky

Reputation: 53563

You can set STDIN to be non-blocking via the stream_set_blocking() function.

function stdin()
{
    $stdin = '';
    $fh = fopen('php://stdin', 'r');
    stream_set_blocking($fh, false);
    while (($line = fgets($fh)) !== false) {
        $stdin .= $line;
    }
    return $stdin;
}

$stdin = stdin(); // returns the contents of STDIN or empty string if nothing is ready

Obviously, you can change the use of line-at-a-time fgets() to hunk-at-a-time fread() as per your needs.

Upvotes: 3

Related Questions