Voting

: three plus five?
(Example: nine)

The Note You're Voting On

exel at example dot com
11 years ago
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
// make gz file
$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");

// open process
$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");

// set both pipes non-blocking
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)
{
// if yo remove this paused retries, process may fail
usleep(200000);
$try--;
if(!
$try)
throw new
Exception("fwrite error");
}
$str=substr($str, $len);
}
echo
strlen($text)."\n";
}
fclose($fd);
fclose($pipes[0]);

// reading the rest of output stream
stream_set_blocking($pipes[1], 1);
while(!
feof($pipes[1]))
{
$s=fread($pipes[1], 16384);
$text.=$s;
}

echo
strlen($text)." / 3 300 000\n";
?>

<< Back to user notes page

To Top