Note that when you call an external script and retrieve large amounts of data from STDOUT and STDERR, you may need to retrieve from both alternately in non-blocking mode (with appropriate pauses if no data is retrieved), so that your PHP script doesn't lock up. This can happen if you waiting on activity on one pipe while the external script is waiting for you to empty the other, e.g:
<?php
$read_output = $read_error = false;
$buffer_len = $prev_buffer_len = 0;
$ms = 10;
$output = '';
$read_output = true;
$error = '';
$read_error = true;
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
while ($read_error != false or $read_output != false)
{
if ($read_output != false)
{
if(feof($pipes[1]))
{
fclose($pipes[1]);
$read_output = false;
}
else
{
$str = fgets($pipes[1], 1024);
$len = strlen($str);
if ($len)
{
$output .= $str;
$buffer_len += $len;
}
}
}
if ($read_error != false)
{
if(feof($pipes[2]))
{
fclose($pipes[2]);
$read_error = false;
}
else
{
$str = fgets($pipes[2], 1024);
$len = strlen($str);
if ($len)
{
$error .= $str;
$buffer_len += $len;
}
}
}
if ($buffer_len > $prev_buffer_len)
{
$prev_buffer_len = $buffer_len;
$ms = 10;
}
else
{
usleep($ms * 1000); if ($ms < 160)
{
$ms = $ms * 2;
}
}
}
return proc_close($process);
?>