Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: Adding Arrow Key Support to STDIN/Single Character Processing

In PHP, I can read in input from a command line program with the following code

$stream = STDIN;
$test = fgets($stream);
echo $test;

This works well for simple input. However, if I try to use something like an back arrow key, my shell looks like the following

This is a test^[[D^[[D^[[D    

i.e., the arrow key escape sequence of ^[[D is sent to the shell. PHP itself will interpret the arrow keys -- i.e. inputing this

This is a test^[[D^[[D^[[D^[[Dsecond test     

will output this

This is a second test

However, I'd like the shell to "correctly" (i.e. do what I think they should do, not literally what I sent) interpret the arrow keys so the insertion point moves while typing.

Is this possible in PHP? With an extension? Without an extension? I've tried variations of fgets($stream, 1) but it seems like PHP just hangs until the user inputs an enter key.

like image 732
Alan Storm Avatar asked Feb 15 '16 19:02

Alan Storm


1 Answers

A bit tricky but found a way using the mbstring library:

// stream_set_blocking(STDIN, false); // Do not wait
while ($c = fread(STDIN, 16)) {
      $c = preg_replace('/[^[:print:]\n]/u', '', mb_convert_encoding($c, 'UTF-8', 'UTF-8'));
      /* Up arrow */
      if ($c === "[A"){
        echo "UP";     
      }
      /* Down arrow */
      if ($c === "[B"){
        echo "DOWN";
      }
      /* Right arrow */
      if ($c === "[C"){
        echo "RIGHT";
      }
      /* LEFT arrow */
      if ($c === "[D"){
       echo "LEFT";
      } 
  }

Hide the shell character printing:

system("stty -echo");

Restore at script end:

stty echo
like image 65
NVRM Avatar answered Oct 16 '22 09:10

NVRM