PHP:PHP手册-Manual

uqjltbpv  于 2023-06-04  发布在  PHP
关注(0)|答案(3)|浏览(149)

在PHP中,我可以使用以下代码从命令行程序读入输入

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

这对于简单的输入很有效。但是,如果我尝试使用后退箭头键之类的东西,我的shell看起来像下面这样

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

即,向 shell 发送^[[D的箭头键转义序列。PHP本身将解释箭头键--即输入此

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

将输出此

This is a second test

但是,我希望shell能够“正确”(即做我认为他们应该做的,而不是字面上我发送的)解释箭头键,以便插入点在键入时移动。
这在PHP中可能吗?有分机吗?没有延期?我试过fgets($stream, 1)的变体,但似乎PHP只是挂起,直到用户输入回车键。

ars1skjm

ars1skjm1#

有点棘手,但找到了使用mbstring库的方法:

// 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";
      } 
  }

隐藏 shell 字符打印:

system("stty -echo");

在脚本结束时恢复:

stty echo
mwg9r5ms

mwg9r5ms2#

没有纯PHP的方法:http://php.net/fgetc(参见注解)

zzoitvuj

zzoitvuj3#

下面的函数将等待直到用户输入一个字符,然后立即返回。此方法支持多字节字符,因此也适用于检测箭头键按下。

function waitForInput(){

    $input = '';

    $read = [STDIN];
    $write = null;
    $except = null;

    readline_callback_handler_install('', function() {});

    // Read characters from the command line one at a time until there aren't any more to read
    do{
        $input .= fgetc(STDIN);
    } while(stream_select($read, $write, $except, 0, 1));

    readline_callback_handler_remove();

    return $input;

}

下面是使用上述函数识别箭头键按下的示例:

$input = waitForInput();

switch($input){
    case chr(27).chr(91).chr(65):
        print 'Up Arrow';
        break;
    case chr(27).chr(91).chr(66):
        print 'Down Arrow';
        break;
    case chr(27).chr(91).chr(68):
        print 'Left Arrow';
        break;
    case chr(27).chr(91).chr(67):
        print 'Right Arrow';
        break;
    default:
        print 'Char: '.$input;
        break;
}

相关问题