【问题标题】:How to check if bash input is being redirect to PHP script?如何检查 bash 输入是否被重定向到 PHP 脚本?
【发布时间】:2017-04-07 14:05:42
【问题描述】:

我正在编写一个 PHP 脚本,我希望能够选择性地使用文件作为脚本输入。这样:

$ php script.php < file.txt

实际上,我可以使用 file_get_contents 做到这一点:

$data = file_get_contents('php://stdin');

但是,如果我没有将文件传递给输入,脚本会无限期挂起,等待输入。

我尝试了以下方法,但没有成功:

$data = '';
$in = fopen('php://stdin', 'r');
do {
    $bytes = fread($in, 4096);
    // Maybe the input will be empty here?! But no, it's not :(
    if (empty($bytes)) {
        break;
    }
    $data .= $bytes;
} while (!feof($in));

脚本等待fread 返回一个值,但它永远不会返回。我猜它会像 file_get_contents 一样等待一些输入。

另一个尝试是用while { ... } 替换do { ... } while 循环,在尝试读取输入之前检查EOF。但这也没有用。

关于如何实现这一目标的任何想法?

【问题讨论】:

  • @JustOnUnderMillions 也许我对 PHP 客户端的要求太多了,但是还有其他 非 PHP 命令行程序实现了这个逻辑——读取输入或忽略/退出。
  • 是的,你是对的。我走错了车道。 @Alex Howansky 明白了。

标签: php bash stdin


【解决方案1】:

您可以通过stream_set_blocking() 函数将 STDIN 设置为非阻塞。

function stdin()
{
    $stdin = '';
    $fh = fopen('php://stdin', 'r');
    stream_set_blocking($fh, false);
    while (($line = fgets($fh)) !== false) {
        $stdin .= $line;
    }
    return $stdin;
}

$stdin = stdin(); // returns the contents of STDIN or empty string if nothing is ready

显然,您可以根据需要将每次使用 line-at-a-time fgets() 更改为 hunk-at-a-time fread()

【讨论】:

  • 正如我从 OP 中了解的那样,我认为这与阻止 IO 无关,而是关于检查输入是否 isset ,“但是,如果我不将文件传递给输入,则脚本无限期挂起,等待输入。'
  • 对——这项技术将缓解这个问题。如果 STDIN 上没有可用的输入,此函数将立即返回一个空字符串。
  • @AlexHowansky,它按我想要的方式工作。我不知道stream_set_blocking 功能。
猜你喜欢
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
  • 1970-01-01
  • 2011-09-22
  • 2014-06-15
  • 1970-01-01
相关资源
最近更新 更多