PHP CLI - 在后台执行操作的同时获取用户输入

Nie*_*sol 2 php io command-line-interface

我正在开发一款用 PHP 编写并在控制台中运行的游戏。回想一下旧的 MUD 和其他基于文本的游戏,甚至一些 ASCII 艺术!

不管怎样,我想做的是让事情发生的同时也接受用户输入。

例如,假设这是一个两人游戏,玩家 1 正在等待玩家 2 采取行动。只需收听消息即可轻松完成此操作。

但是如果玩家 1 想要更改一些选项怎么办?如果他们想查看游戏状态各方面的详细信息怎么办?输掉比赛又怎样?在等待对手采取行动时,玩家可能想做很多事情。

不幸的是,我现在拥有的最好的结果是 Ctrl+C 完全杀死了程序。然后另一个玩家将被挂起,直到连接断开。哦,比赛彻底失败了。

我通过 获取用户输入fgets(STDIN)。但这会阻止执行,直到收到输入为止(这通常是一件好事)。

像这样的控制台程序是否可以同时处理输入和输出?或者我应该看看其他界面?

Mat*_*hew 5

简而言之,PHP 不是为此构建的,但您可能会从这些扩展之一中获得一些帮助。我不确定它们有多彻底,但您可能确实想使用文本 UI 库。(实际上您可能不想为此使用 PHP。)

STDIN话虽如此,您需要逐个字符地获取非阻塞输入。不幸的是,从 PHP 的角度来看,大多数终端都是缓冲的,因此在按下 Enter 之前你不会得到任何东西。

如果您stty -icanon在终端上运行(或操作系统的等效程序)以禁用缓冲,则以下短程序基本上可以工作:

<?php

stream_set_blocking(STDIN, false);

$line = '';

$time = microtime(true);

$prompt = '> ';

echo $prompt;

while (true)
{
  if (microtime(true) - $time > 5)
  {
    echo "\nTick...\n$prompt$line";
    $time = microtime(true);
  }

  $c = fgetc(STDIN);
  if ($c !== false)
  {
    if ($c != "\n")
      $line .= $c;
    else
    {
      if ($line == 'exit' || $line == 'quit')
        break;
      else if ($line == 'help')
        echo "Type exit\n";
      else
        echo "Unrecognized command.\n";

      echo $prompt;
      $line = '';
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

(它依赖于启用本地回显来打印键入的字符。)

正如你所看到的,我们只是永远循环下去。如果存在字符,则将其添加到$line. 如果按下 Enter 键,则处理$line。同时,我们每五秒滴答一次,只是为了表明在等待输入时我们可以做其他事情。(这将消耗最大的 CPU;您必须发出 asleep()来解决这个问题。)

这本身并不是一个实际的例子,但也许会让你思考正确的方向。