note 94563 deleted from function.proc-open by danbrown

From: Date: Thu, 12 Nov 2009 13:32:56 +0000
Subject: note 94563 deleted from function.proc-open by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-162805@lists.php.net to get a copy of this message
Note Submitter: gabelager at gabelager dot net ---- Here is a combined implementation of the example code and the comments from simeonl at dbc dot co dot nz 04-Mar-2009 02:39 <?php function openProcess($command, $cwd = NULL, $env = NULL) { $descriptorspec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child will read from 1 => array("pipe", "w"), // stdout is a pipe that the child will write to 2 => array("pipe", "w") // stderr is a pipe that the child will write to ); $process = proc_open($command, $descriptorspec, $pipes, $cwd, $env); if (is_resource($process)) { //$pipes now looks like this: //0 => writeable handle connected to child stdin //1 => readable handle connected to child stdout //2 => readable handle connected to child stderr //Some excellent pipe-reading code that prevents deadlocks. //Taken verbatim (and cleaned-up for formatting) from: //http://us3.php.net/manual/en/function.proc-open.php#89338 $readOutput = $readError = false; $bufferLen = $prev_buffer_len = 0; $ms = 10; $output = ''; $readOutput = true; $error = ''; $readError = 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 ($readError != false or $readOutput != false) { if ($readOutput != false) { if (feof($pipes[1])) { fclose($pipes[1]); $readOutput = false; } else { $str = fgets($pipes[1], 1024); $len = strlen($str); if ($len) { $output .= $str; $bufferLen += $len; } } } if ($readError != false) { if (feof($pipes[2])) { fclose($pipes[2]); $readError = false; } else { $str = fgets($pipes[2], 1024); $len = strlen($str); if ($len) { $error .= $str; $bufferLen += $len; } } } if ($bufferLen > $prev_buffer_len) { $prev_buffer_len = $bufferLen; $ms = 10; } else { usleep($ms * 1000); // sleep for $ms milliseconds if ($ms < 160) { $ms = $ms * 2; } } } //Pipes 1 and 2 have already been closed. fclose($pipes[0]); //It is important to close any pipes before calling //proc_close in order to avoid a deadlock. $retVal['exitCode'] = proc_close($process); $retVal['stdOut'] = $output; $retVal['stdErr'] = $error; return $retVal; } else { return FALSE; } } ?>

« previous php.notes (#162805) next »