【问题标题】:How do I flush STDIN in a PHP console application?如何在 PHP 控制台应用程序中刷新 STDIN?
【发布时间】:2014-10-26 18:13:10
【问题描述】:

我有一个用 PHP 构建的简单命令行实用程序,它运行良好。不幸的是,我们现在有一些不太精明的用户在处理数据时敲击键盘。

有没有办法刷新 STDIN,所以它只从我使用 fgetc 时开始缓冲数据?

我已经尝试打开自己的 STDIN 管道,甚至通过循环其中的内容来刷新缓冲区,哪种工作但不能处理多个 CR。

Rewind 和 fseek 似乎对 PHP 中的 STDIN 没有任何作用。

这似乎是一个普遍的问题,但并不多。

PHP 版本 5.3.3

(如果不需要,我不想使用 ncurses)

任何 fgets 或 fgetc 都会显示我的问题。例如,如果您有一个提示指示某些内容正在“处理”,然后开始输入,则输入会在 STDIN 中缓冲,因此当您稍后实际提示用户输入某些内容时,会将他们输入的内容添加到缓冲区中。因此,如果他们在“处理”时键入“abc”,然后您提示输入一些内容,他们的输入是“abc”加上他们在您进入 fgets 或 fgetc 时在提示符下键入的任何内容。因此,如果有人一直按 ENTER 并且您正在使用 fgets(或 fgetc 等待“\n”),那么您会过早地继续代码。

例如:

echo "Processing";
sleep(10); // HIT ENTER A FEW TIMES HERE
echo "Input Something: ";
// REALLY NEED TO FLUSH STDIN HERE SOMEHOW
fgets(STDIN);

【问题讨论】:

  • 我不明白这个问题。您能否展示一个简单的代码示例以及预期的功能?
  • PHP 根本没有线程,我很好奇谁认为在 Python 或 Java 上用 PHP 编写 CLI 实用程序是个好主意。使用线程技术你可能不会有这个问题,但我不确定到底是什么问题..
  • @RaggaMuffin-420 这与线程有什么关系?
  • 我倾向于说,它无法实现。但我仍然不确定

标签: php console stdin flush command-line-interface


【解决方案1】:

似乎 PHP "readline" 是处理这个问题的好方法,我会用它。

谢谢大家!

【讨论】:

【解决方案2】:

迟到总比永不好,但您应该能够使用 stream_select

<?php

    while(stream_select($in = [STDIN], $out = [], $oob = [],0)){
        fgetc(STDIN);
    }

?>

基本上,这将查看给定流上是否有可用数据,如果有则从中读取数据(并且不对其执行任何操作)

在此之后,您可以从标准输入读取以获取您想要的输入

【讨论】:

    【解决方案3】:

    您是否尝试在每次提示后关闭 STDIN 流?我认为这就是 Composer 的编写方式。所以基本上你会去 fopen() fgetc() fclose() .... 直到下一个提示。对我有用,但我使用的是 PHP 5.5

    【讨论】:

    • 虽然您可以在标准输入的句柄上调用fclose(),但您不能真正关闭它,因为 php 解释器仍然维护标准输入。这个答案是完全错误的
    • 无论如何都不优雅。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    相关资源
    最近更新 更多