在 PHP CLI 中的 STDIN 上实现非阻塞

2022-08-30 22:18:58

无论如何,有没有用非阻塞的PHP读取:STDIN

我试过这个:

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上)?


答案 1

这是我能想到的。它在Linux中工作正常,但在Windows上,一旦我按下一个键,输入就会被缓冲,直到按下Enter键。我不知道在流上禁用缓冲的方法。

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

?>

答案 2

只是一个通知,即非阻塞STDIN工作,现在。


推荐