Неблокирование на STDIN в PHP CLI - PullRequest
14 голосов
/ 20 февраля 2012

Есть ли в любом случае для чтения из 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 ]

12 голосов
/ 15 марта 2012

Вот что я мог придумать.Он отлично работает в 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
    }
}

?>
1 голос
/ 31 января 2018

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

1 голос
/ 21 февраля 2012

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...