Есть ли в любом случае, чтобы читать из STDIN
с PHP, который не блокирует:
Я попробовал это:
stream_set_blocking(STDIN, false); echo fread(STDIN, 1);
и это:
$stdin = fopen('php://stdin', 'r'); stream_set_blocking($stdin, false); echo 'Press enter to force run command...' . PHP_EOL; echo fread($stdin, 1);
но он все еще блокируется, пока fread
получит некоторые данные.
Я заметил несколько открытых отчетов об ошибках (7 лет), поэтому, если это невозможно сделать, кто-нибудь знает какие-либо сырые хаки, которые могут это сделать (в Windows и Linux)?
Вот что я мог придумать. Он отлично работает в Linux, но в Windows, как только я нажимаю клавишу, вход буферизуется до нажатия клавиши ввода. В настоящее время я пытаюсь найти способ отключить буферизацию в потоке или, в частности, STDIN в PHP.
<?php function non_block_read($fd, &$data) { $read = array($fd); $write = array(); $except = array(); $result = stream_select($read, $write, $except, 0); if($result === false) throw new Exception('stream_select failed'); if($result === 0) return false; $data = stream_get_line($fd, 1); return true; } while(1) { $x = ""; if(non_block_read(STDIN, $x)) { echo "Input: " . $x . "\n"; // handle your input here } else { echo "."; // perform your processing here } } ?>
Петах, я не могу помочь с этой стороной PHP напрямую, но я могу отнести вас к статье, которую я провел некоторое время назад, когда кто-то эмулировал транзисторы, тестируя в сценарии оболочки наличие ожидающих данных для именованного канала , Это увлекательное чтение, и он использует shell-скрипты для совершенно нового уровня geekiness. 🙂
Статья находится здесь: http://www.linusakesson.net/programming/pipelogic/
Поэтому … в ответ на ваш запрос «грубые хаки», я полагаю, вы могли бы шунтировать свой stdio через именованные каналы, а затем exec()
инструмент, источник которого включен в URL выше, чтобы проверить, ожидает ли что-либо, труба. Вы, вероятно, захотите разработать некоторые функции-обертки, чтобы помочь в работе.
Я подозреваю, что конвейерное решение – только для Linux или, по крайней мере, потребует операционной системы, подобной UNIX. Не знаю, как это можно сделать в Windows.