Voting

: min(zero, six)?
(Example: nine)

The Note You're Voting On

simeonl at dbc dot co dot nz
16 years ago
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);

// dual reading of STDOUT and STDERR stops one full pipe blocking the other, because the external script is waiting
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); // sleep for $ms milliseconds
if ($ms < 160)
{
$ms = $ms * 2;
}
}
}

return
proc_close($process);
?>

<< Back to user notes page

To Top