Неблокирующийся стандартный ввод в командной строке PHP
Есть ли в любом случае, чтобы читать из 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)?
3 answers
Вот что я мог бы придумать. Это прекрасно работает в Linux, но в Windows, как только я нажимаю клавишу, ввод буферизуется до тех пор, пока не будет нажата клавиша enter. В настоящее время я пытаюсь найти способ отключить буферизацию в потоке или, в частности, в 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-стороной этого напрямую, но я могу сослаться на статью, с которой я столкнулся некоторое время назад, в которой кто-то эмулировал транзисторы, проверяя в сценарии оболочки наличие ожидающих данных для именованного канала. Это увлекательное чтение, которое выводит сценарии оболочки на совершенно новый уровень сложности. :-)
Статья находится здесь: http://www.linusakesson.net/programming/pipelogic/
Итак... в ответ на ваш запрос "грубые взломы" я предположим, вы могли бы перенаправить свой stdio через именованные каналы, затем exec()
инструмент, источник которого указан в приведенном выше URL-адресе, чтобы проверить, ожидает ли что-либо отправки по каналу. Вы, вероятно, захотите разработать некоторые функции-оболочки, чтобы помочь с вещами.
Я подозреваю, что решение pipelogic предназначено только для Linux или, по крайней мере, потребует операционной системы, подобной unix. Понятия не имею, как это можно сделать в Windows.
Просто обратите внимание, что теперь неблокирующий стандартный ввод работает.