Nie*_*sol 2 php io command-line-interface
我正在开发一款用 PHP 编写并在控制台中运行的游戏。回想一下旧的 MUD 和其他基于文本的游戏,甚至一些 ASCII 艺术!
不管怎样,我想做的是让事情发生的同时也接受用户输入。
例如,假设这是一个两人游戏,玩家 1 正在等待玩家 2 采取行动。只需收听消息即可轻松完成此操作。
但是如果玩家 1 想要更改一些选项怎么办?如果他们想查看游戏状态各方面的详细信息怎么办?输掉比赛又怎样?在等待对手采取行动时,玩家可能想做很多事情。
不幸的是,我现在拥有的最好的结果是 Ctrl+C 完全杀死了程序。然后另一个玩家将被挂起,直到连接断开。哦,比赛彻底失败了。
我通过 获取用户输入fgets(STDIN)。但这会阻止执行,直到收到输入为止(这通常是一件好事)。
像这样的控制台程序是否可以同时处理输入和输出?或者我应该看看其他界面?
简而言之,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()来解决这个问题。)
这本身并不是一个实际的例子,但也许会让你思考正确的方向。