Как определить, является ли поток STDIN в PHP

#php #command-line-interface

#php #интерфейс командной строки

Вопрос:

Я работаю над некоторыми инструментами PHP cli для фреймворка php, и возникает ситуация, когда мой скрипт либо считывает данные из файла, либо STDIN . Поскольку не все операции (например, fseek() ) допустимы в STDIN , я ищу способ определить это.

Комментарии:

1. Я не понимаю. Конечно, вы должны знать, передаете ли вы stdin стандартный файл определенной функции или нет? Вы имеете в виду, что не знаете, stdin соответствует ли TTY или файлу, который передается по конвейеру?

2. Поскольку не имеет значения, поступают ли данные stdin из tty или файла, касающегося возможностей поиска и т.д., я уверен, что ему не нужен PHP-эквивалент isatty() . Я предполагаю, что у него есть функция, которая принимает fd, и он хочет сделать свой код универсальным, чтобы он мог работать как с обычным файлом, так и с stdin.

3. @ThiefMaster Это именно то, что нужно.

Ответ №1:

Оказывается, что функция stream_get_meta_data() предоставляет решение, при вызове в standard in результат:

 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)
}
  

Таким образом, вы можете выполнить простое сравнение строк в uri:

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

Это решение будет работать независимо от того, STDIO используется постоянный поток или старый fopen('php://stdin', 'r') , который все еще скрывается в старом коде.

Ответ №2:

Просто проверьте if($fp === STDIN)

Комментарии:

1. Я думал об этом, но я работаю с устаревшим кодом, который использует более старый fopen('php://stdin.. синтаксис, что приводит к сбою сравнения. Это должно сработать, если вместо этого использовать константу.