Неблокирующийся стандартный ввод в командной строке 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)?

 14
Author: Petah, 2012-02-20

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

?>
 12
Author: Martin, 2012-03-14 22:16:47

Петах, я не могу помочь с PHP-стороной этого напрямую, но я могу сослаться на статью, с которой я столкнулся некоторое время назад, в которой кто-то эмулировал транзисторы, проверяя в сценарии оболочки наличие ожидающих данных для именованного канала. Это увлекательное чтение, которое выводит сценарии оболочки на совершенно новый уровень сложности. :-)

Статья находится здесь: http://www.linusakesson.net/programming/pipelogic/

Итак... в ответ на ваш запрос "грубые взломы" я предположим, вы могли бы перенаправить свой stdio через именованные каналы, затем exec() инструмент, источник которого указан в приведенном выше URL-адресе, чтобы проверить, ожидает ли что-либо отправки по каналу. Вы, вероятно, захотите разработать некоторые функции-оболочки, чтобы помочь с вещами.

Я подозреваю, что решение pipelogic предназначено только для Linux или, по крайней мере, потребует операционной системы, подобной unix. Понятия не имею, как это можно сделать в Windows.

 1
Author: ghoti, 2012-02-20 22:24:31

Просто обратите внимание, что теперь неблокирующий стандартный ввод работает.

 0
Author: Sergey NN, 2018-01-31 14:51:51