无论如何,使用非阻塞的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上)?
答案 0 :(得分:12)
这是我能想到的。它在Linux中工作正常,但在Windows上,只要我按下一个键,输入就会被缓冲,直到按下enter键。我目前正试图找到一种方法来禁用流上的缓冲,或者特别是在PHP中的STDIN上。
<?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 :(得分:1)
Petah,我无法直接帮助解决这方面的问题,但是我可以向您推荐一篇我之前跑过的文章,其中某人通过在shell脚本中测试是否存在待处理数据来模拟晶体管命名管道。这是一个引人入胜的阅读,并将shell脚本带入了一个全新的极客。 : - )
文章在这里:http://www.linusakesson.net/programming/pipelogic/
所以...在回答你的“粗暴黑客”请求时,我想你可以通过命名管道分流你的stdio,然后exec()
工具的源代码包含在上面的URL中,以测试是否有任何东西在等待通过管道发送。你可能想要开发一些包装函数来帮助解决问题。
我怀疑pipelogic解决方案仅限Linux,或者至少需要类似unix的操作系统。不知道如何在Windows上实现这一目标。
答案 2 :(得分:1)
请注意,非阻塞STDIN正在工作,现在。
答案 3 :(得分:0)
display: inline-block;