如何在PHP中处理标准输入并输出到标准输出?

4

我正在尝试编写一个简单的php脚本,从stdin接收数据,处理后再将其写入stdout。我知道PHP可能不是这种事情的最佳语言,但我需要现有的功能。

我已经尝试过

<?php
$file = file_get_contents("php://stdin", "r");
echo $file;
?>

但它不起作用。我像这样调用它:echo -e "\ndata\n" | php script.php | cat 并没有收到错误信息。我正在尝试构建的脚本实际上将成为更大管道的一部分。
有什么线索可以解释为什么它不起作用吗?
注:我在 PHP 方面经验不是很丰富。
3个回答

6
如果你正在使用管道传输数据,你应该缓冲输入而不是一次性处理所有数据,像*nix工具一样逐行处理。
文件顶部的SheBang语句允许您直接执行文件,而不必在命令行中调用php。
将以下代码保存到test.php并运行。
cat test.php | ./test.php

查看结果。

#!php
<?php
$handle = fopen('php://stdin', 'r');
$count = 0;
while(!feof($handle)) {
    $buffer = fgets($handle);
    echo $count++, ": ", $buffer;
}
fclose($handle);

1
如果在执行时没有STDIN可用,那怎么办?这不会让脚本挂起吗? - CMCDragonkai
我默认在PHP中STDIN始终可用,但它的缓冲区可能为空(或者更好的说法是包括EOF)。 - Kamafeather

3
要将一个php脚本放置在管道中,您可以使用以下方法:
xargs -d "\n" ./mysrcipt.php --foo

当有很多行/参数时,./myscript.php会被调用几次,但始终带有--foo。

例如:

./myscript.php:
#!/bin/php
<?php
foreach($args as $key => $value){
 echo "\n".$key.":".$value;
}
?>
cat -n1000 /path/file | xargs -d "\n" ./myscript.php --foo | less

将使用echo向标准输出/less输出两次脚本:

0:./myscript
1:--foo
2:[file-line1]
3:[file-line2]
...
800:[file-line799]
0:./myscript
1:--foo
2:[file-line800]
...

source


谢谢Compie。我负担不起像xargs那样将初始流分成两部分的代价。PHP脚本必须拥有整个流。难道真的没有办法在管道中使用PHP而不需要采取这种方法吗? - brice

0

好的,搞定了。

<?php
  $input_stream = fopen("php://stdin","r");
  $text="";
  while($line = fgets($input_stream,4096)){ // Note 4k lines, should be ok for most purposes
    $text .= $line;
  }

  fclose($input_stream);
  print($text);
?>

来自PHPBuilder的一份食谱。


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