pipe communications may break brains off. i want to share some stuff to avoid such result.
for proper control of the communications through the "in" and "out" pipes of the opened sub-process, remember to set both of them into non-blocking mode and especially notice that fwrite may return (int)0 but it's not an error, just process might not except input at that moment.
so, let us consider an example of decoding gz-encoded file by using funzip as sub-process: (this is not the final version, just to show important things)
<?php
$fd=fopen("/tmp/testPipe", "w");
for($i=0;$i<100000;$i++)
fwrite($fd, md5($i)."\n");
fclose($fd);
if(is_file("/tmp/testPipe.gz"))
unlink("/tmp/testPipe.gz");
system("gzip /tmp/testPipe");
$pipesDescr=array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("file", "/tmp/testPipe.log", "a"),
);
$process=proc_open("zcat", $pipesDescr, $pipes);
if(!is_resource($process)) throw new Exception("popen error");
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
$text="";
$fd=fopen("/tmp/testPipe.gz", "r");
while(!feof($fd))
{
$str=fread($fd, 16384*4);
$try=3;
while($str)
{
$len=fwrite($pipes[0], $str);
while($s=fread($pipes[1], 16384*4))
$text.=$s;
if(!$len)
{
usleep(200000);
$try--;
if(!$try)
throw new Exception("fwrite error");
}
$str=substr($str, $len);
}
echo strlen($text)."\n";
}
fclose($fd);
fclose($pipes[0]);
stream_set_blocking($pipes[1], 1);
while(!feof($pipes[1]))
{
$s=fread($pipes[1], 16384);
$text.=$s;
}
echo strlen($text)." / 3 300 000\n";
?>