2010-07-14 14 views
4

J'essaye d'écrire un manuscrit de php simple pour prendre des données de stdin, le traiter, puis l'écrire à stdout. Je sais que PHP n'est probablement pas le meilleur langage pour ce genre de choses, mais il existe des fonctionnalités dont j'ai besoin.Comment faire pour traiter stdin stdout en php?

J'ai essayé

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

mais il ne fonctionne pas. Je l'invoque comme ceci: echo -e "\ndata\n" | php script.php | cat. et n'obtient aucun message d'erreur. Le script que j'essaie de construire fera en réalité partie d'un plus grand pipeline.

Des indices pour expliquer pourquoi cela ne fonctionne pas? PS: Je ne suis pas très expérimenté avec PHP.

Répondre

5

Si vous effectuez une tuyauterie, vous souhaiterez mettre en tampon l'entrée, au lieu de la traiter en une fois, il suffit de passer une ligne à la fois, comme c'est le cas pour les outils * nix. Le SheBang au-dessus du fichier vous permet d'exécuter le fichier directement, au lieu d'avoir à appeler php dans la ligne de commande.

Enregistrez ce qui suit à Test.php et exécuter

cat test.php | ./test.php 

pour voir les résultats.

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

Que se passe-t-il s'il n'y a pas de STDIN disponible au moment de l'exécution? Cela ne ferait-il pas tomber le script? – CMCDragonkai

3

Pour placer un script php dans une conduite, vous pouvez utiliser:

xargs -d "\n" ./mysrcipt.php --foo 

Avec de nombreuses lignes/args le ./myscript.php sera appelé une ou deux fois, mais toujours avec --foo.

.: par exemple

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

appellera le script deux fois avec écho stdout/moins:

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

source

+0

merci compie. Je ne peux pas me permettre d'avoir le flux initial divisé en deux comme xargs le ferait. Le script PHP doit avoir le tout. N'y at-il vraiment aucun moyen d'utiliser php dans un tuyau sans avoir recours à des trucs comme ça? – brice

0

droit, il a obtenu de travail.

<?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); 
?> 

à partir d'une recette à PHPBuilder.