PHP CLI:如何从TTY中读取输入的单个字符(无需等待回车键)? [英] PHP CLI: How to read a single character of input from the TTY (without waiting for the enter key)?

查看:125
本文介绍了PHP CLI:如何从TTY中读取输入的单个字符(无需等待回车键)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想一次从PHP的命令行中一次读取一个字符,但是似乎从某处阻止了某种输入缓冲.

I want to read a single character at-a-time from the command line in PHP, however it seems as though there is some kind of input buffering from somewhere preventing this.

考虑以下代码:

#!/usr/bin/php
<?php
echo "input# ";
while ($c = fread(STDIN, 1)) {
    echo "Read from STDIN: " . $c . "\ninput# ";
}
?>

输入"foo"作为输入(并按回车键),我得到的输出是:

Typing in "foo" as the input (and pressing enter), the output I am getting is:

input# foo
Read from STDIN: f
input# Read from STDIN: o
input# Read from STDIN: o
input# Read from STDIN: 

input# 

期望的输出是:

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 is, with characters being read and processed as they are typed).

但是,当前,仅在按下Enter键后才能读取每个字符.我怀疑TTY正在缓冲输入.

However, currently, each character is being read only after enter is pressed. I have a suspicion the TTY is buffering the input.

我最终希望能够读取按键,例如UP箭头,DOWN箭头等.

Ultimately I want to be able to read keypresses such as UP arrow, DOWN arrow, etc.

推荐答案

对我来说,解决方案是在TTY上设置-icanon模式(使用stty).例如:

The solution for me was to set -icanon mode on the TTY (using stty). Eg.:

stty -icanon

所以,现在可以使用的代码是:

So, the the code that now works is:

#!/usr/bin/php
<?php
system("stty -icanon");
echo "input# ";
while ($c = fread(STDIN, 1)) {
    echo "Read from STDIN: " . $c . "\ninput# ";
}
?>

输出:

input# fRead from STDIN: f
input# oRead from STDIN: o
input# oRead from STDIN: o
input# 
Read from STDIN: 

input# 

此处给出答案的提示:

Props to the answer given here:
Is there a way to wait for and get a key press from a (remote) terminal session?

有关更多信息,请参见:
http://www.faqs.org/docs/Linux -HOWTO/Serial-Programming-HOWTO.html#AEN92

For more information, see:
http://www.faqs.org/docs/Linux-HOWTO/Serial-Programming-HOWTO.html#AEN92

完成操作后,别忘了恢复TTY ...

Don't forget to restore the TTY when you're done with it...

恢复tty配置

通过在更改终端状态之前保存tty状态,将终端重置回原来的状态.完成后,您可以恢复到该状态.

Resetting the terminal back to the way it was can be done by saving the tty state before you make changes to it. You can then restore to that state when you're done.

例如:

<?php

// Save existing tty configuration
$term = `stty -g`;

// Make lots of drastic changes to the tty
system("stty raw opost -ocrnl onlcr -onocr -onlret icrnl -inlcr -echo isig intr undef");

// Reset the tty back to the original configuration
system("stty '" . $term . "'");

?>

这是保存tty并将其恢复到用户开始之前的方式的唯一方法.

This is the only way to preserve the tty and put it back how the user had it before you began.

请注意,如果您不担心保留原始状态,只需执行以下操作即可将其重置为默认的健全"配置:

Note that if you're not worried about preserving the original state, you can reset it back to a default "sane" configuration simply by doing:

<?php

// Make lots of drastic changes to the tty
system("stty raw opost -ocrnl onlcr -onocr -onlret icrnl -inlcr -echo isig intr undef");

// Reset the tty back to sane defaults
system("stty sane");

?>

这篇关于PHP CLI:如何从TTY中读取输入的单个字符(无需等待回车键)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆