Как обработать стандартный ввод в стандартный вывод php? - PullRequest
4 голосов
/ 14 июля 2010

Я пытаюсь написать простой php-скрипт для получения данных из stdin, обработать их и записать в stdout. Я знаю, что PHP, вероятно, не лучший язык для такого рода вещей, но есть существующая функциональность, которая мне нужна.

Я пробовал

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

но это не работает. Я вызываю это так: echo -e "\ndata\n" | php script.php | cat. и не получить сообщений об ошибках. Скрипт, который я пытаюсь создать, на самом деле будет частью большого конвейера.

Есть какие-нибудь подсказки, почему это не работает?

PS: я не очень разбираюсь в PHP.

Ответы [ 3 ]

6 голосов
/ 14 июля 2010

Если вы работаете с конвейером, вам нужно будет буферизовать ввод, вместо того, чтобы обрабатывать все сразу, просто переходите по одной строке за раз, как это стандартно для * nix инструментов.файл позволяет вам выполнить файл напрямую, вместо того чтобы вызывать 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);
3 голосов
/ 14 июля 2010

Чтобы поместить 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

вызовет сценарий два раза с эхом на стандартный вывод / меньше:

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

источник

0 голосов
/ 14 июля 2010

Да, все заработало.

<?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 .

...