0

I'm working on some PHP cli tools for a php framework and there's a situation where my script either reads from a file or STDIN. Since not all operations (like fseek()) are valid on STDIN, I'm looking for a way to detect this.

Dana the Sane
  • 14,762
  • 8
  • 58
  • 80
  • I don't understand. Surely you must know whether you're passing `stdin` or a standard file to a particular function? Do you mean you don't know whether `stdin` corresponds to a TTY or a file being piped in? – Oliver Charlesworth Apr 06 '11 at 20:12
  • Since it doesn't matter if the data on `stdin` comes from a tty or a file regarding seeking abilities etc, I'm sure he doesn't want a PHP equivalent of `isatty()`. I guess he has a function which accepts an fd and he wants to make his code generic so it can work with both a regular file and stdin. – ThiefMaster Apr 06 '11 at 20:19
  • @ThiefMaster That's exactly it. – Dana the Sane Apr 06 '11 at 20:21

2 Answers2

4

Turns out that the function stream_get_meta_data() provides a solution, when called on standard in, the result is:

array(9) {
  ["wrapper_type"]=>
  string(3) "PHP"
  ["stream_type"]=>
  string(5) "STDIO"
  ["mode"]=>
  string(1) "r"
  ["unread_bytes"]=>
  int(0)
  ["seekable"]=>
  bool(false)
  ["uri"]=>
  string(11) "php://stdin"
  ["timed_out"]=>
  bool(false)
  ["blocked"]=>
  bool(true)
  ["eof"]=>
  bool(false)
}

So you can do a simple string compare on the uri:

function isSTDIN($stream) {
    $meta = stream_get_meta_data($stream);
    return strcmp($meta['uri'], 'php://stdin') == 0;
}

This solution will work whether the constant stream STDIO is used, or the old fopen('php://stdin', 'r'), which still lurks around in old code.

Dana the Sane
  • 14,762
  • 8
  • 58
  • 80
1

Simply check if($fp === STDIN)

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • I thought of that, but I'm working with legacy code that uses the older `fopen('php://stdin..` syntax, making the comparison fail. This should work if use the constant instead. – Dana the Sane Apr 06 '11 at 20:17