我想从PHP的命令行中一次读取一个字符,但是似乎有某种输入缓冲阻止了这一点。
考虑以下代码:
#!/usr/bin/php
<?php
echo "input# ";
while ($c = fread(STDIN, 1)) {
echo "Read from STDIN: " . $c . "\ninput# ";
}
?>
输入“foo”作为输入(并按回车键),我得到的输出是:
input# foo
Read from STDIN: f
input# Read from STDIN: o
input# Read from STDIN: o
input# Read from STDIN:
input#
我 expecting 的输出是:
input# f
input# Read from STDIN: f
input# o
input# Read from STDIN: o
input# o
input# Read from STDIN: o
input#
input# Read from STDIN:
input#
(That在键入字符时读取和处理字符)。
但是,当前,每个字符仅在按下回车键后才被读取。我怀疑TTY正在缓冲输入。
最终,我希望能够阅读按键,如向上箭头,向下箭头等。
5条答案
按热度按时间wsxa1bj11#
对我来说,解决方案是在TTY上设置
-icanon
模式(使用stty
)。例如:所以,现在起作用的代码是:
输出:
支持这里给出的答案:
是否有一种方法可以等待并从(远程)终端会话获得按键?
有关详细信息,请参阅:
http://www.faqs.org/docs/Linux-HOWTO/Serial-Programming-HOWTO.html#AEN92
不要忘记恢复TTY当你完成它...
恢复tty配置
将终端重置回原来的状态可以通过在更改tty状态之前保存它来完成。然后,您可以在完成后恢复到该状态。
例如:
这是保存tty并将其放回用户在开始之前拥有的状态的唯一方法。
请注意,如果您不担心保留原始状态,您可以通过执行以下操作将其重置回默认的“正常”配置:
ou6hu8tu2#
这里有一种方法,它适用于readline和stream函数,而不需要弄乱tty的东西。
在OSX上用PHP 5.5.8测试。
tvokkenx3#
下面的函数是@seb的答案的简化版本,可用于捕获单个字符。它不需要
stream_select
,并使用readline_callback_handler_install
固有的阻塞而不是创建while循环。它还删除了处理程序,以允许进一步的正常输入(如readline)。lndjwyie4#
wj8zmpe15#
下面的函数将等待直到用户输入一个字符,然后立即返回。此方法支持多字节字符,因此也适用于检测箭头键按下。
下面是使用上述函数识别箭头键按下的示例: