PHP CLI: How to read a single character of input from the TTY (without waiting for the enter key)?
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# ";
}
?>
Output:
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?
For more information, see:
http://www.faqs.org/docs/Linux-HOWTO/Serial-Programming-HOWTO.html#AEN92
Don't forget to restore the TTY when you're done with it...
Restoring the tty configuration
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.
For example:
<?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 . "'");
?>
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");
?>
Is it possible to update screen and wait for user input at the same time with PHP?
Go for libevent http://www.php.net/manual/en/book.libevent.php
You can run your main loop while listening to console with a code roughly like this one:
<?php
// you need libevent, installable via PEAR
$forever=true;
$base=event_base_new();
$console=event_buffer_new(STDIN,"process_console");
event_buffer_base_set($console,$base);
event_buffer_enable($console,EV_READ);
while ($forever) {
event_base_loop($base,EVLOOP_NONBLOCK); // Non blocking poll to console listener
//Do your video update process
}
event_base_free($base); //Cleanup
function process_console($buffer,$id) {
global $base;
global $forever;
$message='';
while ($read = event_buffer_read($buffer, 256)) {
$message.=$read;
}
$message=trim($message);
print("[$message]\n");
if ($message=="quit") {
event_base_loopexit($base);
$forever=false;
}
else {
//whatever.....
}
}
Listen to stream from /dev/tty where return key is not necessary
Just a matter of using raw mode, at least with Node.js:
const {ReadStream} = require('stream');
const r = new ReadStream();
r.setRawMode(true);
Related Topics
Accessing Variables and Methods Outside of Class Definitions
Logging in to Joomla 1.5 Using External Form (Not Within Joomla Folder, But on Same Server)
PHP Using Preg_Replace:"Delimiter Must Not Be Alphanumeric or Backslash" Error
Codeigniter Default Controller in a Sub Directory Not Working
Insert Current Date in Datetime Format MySQL
Executing PHP Code Inside a .Js File
How to Add a Class to Every Nth Item in a PHP Loop (Wordpress)
PHP - How to Build Tree Structure List
How to Make Strings "Xml Safe"
Passing Multiple PHP Variables to Shell_Exec()
Another Twitter Oauth Curl Access Token Request That Fails
Getting Actual Value from PHP Simplexml Node