如何检查流是否有任何数据?

5
这是我想要做的事情:
$output = '';
$stream = popen("some-long-running-command 2>&1", 'r');
while (!feof($stream)) {
  $meta = stream_get_meta_data($stream);
  if ($meta['unread_bytes'] > 0) {
    $line = fgets($stream);
    $output .= $line;
  }
  echo ".";
}
$code = pclose($stream);

看起来这段代码不正确,因为它在调用stream_get_meta_data()时被卡住了。那么正确的检查流中是否有可读数据的方法是什么?整个重点在于避免在fgets()处锁定。


fgets() locks because it waits for a "new-line" character. Use stream_get_contents() with the length argument instead: $line = stream_get_contents($stream, $meta['unread_bytes']); - Mike Shiyan
1个回答

7

正确的做法是使用stream_select()函数:

$stream = popen("some-long-running-command 2>&1", 'r');
while (!feof($stream)) {
  $r = array($stream);
  $w = $e = NULL;

  if (stream_select($r, $w, $e, 1)) {
    // there is data to be read
  }
}
$code = pclose($stream);

需要注意的一点是(我不确定)可能是feof()检查在“阻塞”-可能是循环永远不会结束,因为子进程没有关闭其STDOUT描述符。


需要注意的是,就像@DaveRandom所做的那样,如果你要使用NULL,必须将其分配给一个变量,以避免传递非变量引用(这是前三个参数声明的方式)而导致麻烦。请阅读http://php.net/manual/en/function.stream-select.php上的注释。 - Jeff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接