note 110755 modified in function.stream-set-blocking by danbrown

From: Date: Thu, 06 Dec 2012 14:11:26 +0000
Subject: note 110755 modified in function.stream-set-blocking by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-192297@lists.php.net to get a copy of this message
It took me long time to "compile" this code, thanks to set blocking, we can write and read at the same time in proc_open(). Notice how the output from child begins after we feed several lines into it. Also notice that end lines are output *after* we do fclose($pipes[0]); Then we need to continue read until feof(), because fgets() may return false even there are more data to read. For educational reasons, I suggest you to try feeding small file (1-2 KB), medium file (4-5 MB) and huge file ( GB++ ). #!/usr/bin/php <?php $max_buffer = 16 * 1024; $prog = 'cat'; $descr = array( 0 => array("pipe", "r"), // stdin 1 => array("pipe", "w"), // stdout 2 => array("file", "/dev/null", "a") // stderr ); $process = proc_open($prog, $descr, $pipes); foreach($pipes as $f) stream_set_blocking($f, 0); //stream_set_write_buffer($pipes[0], 1*1024*1024); $br = 0; while ( ($line = fgets(STDIN, $max_buffer)) !== false){ $br = $br + strlen($line); $ret = fwrite($pipes[0], $line); if ($ret == false){ echo "error, buffer full?\n"; } $s = fgets($pipes[1], $max_buffer); printf("%12.3f | ", $br / 1024); process_output($s); } //stream_set_blocking($pipes[1], 1); fclose($pipes[0]); while (! feof($pipes[1]) ){ $s = fgets($pipes[1], $max_buffer); if ($s === false) continue; printf("%12s |", "end"); process_output($s); } fclose($pipes[1]); function process_output($s){ $s = trim($s); if (strlen($s) > 50) $s = substr($s, 0, 50) . " [crop]"; printf("%s\n", $s ? $s : "--none--"); } ?> --was-- It took me long time to "compile" this code, thanks to set blocking, we can write and read at the same time in proc_open(). Notice how the output from child begins after we feed several lines into it. Also notice that end lines are output *after* we do fclose($pipes[0]); Then we need to continue read until feof(), because fgets() may return false even there are more data to read. For educational reasons, I suggest you to try feeding small file (1-2 KB), medium file (4-5 MB) and huge file ( GB++ ). #!/usr/bin/php <? $max_buffer = 16 * 1024; $prog = 'cat'; $descr = array( 0 => array("pipe", "r"), // stdin 1 => array("pipe", "w"), // stdout 2 => array("file", "/dev/null", "a") // stderr ); $process = proc_open($prog, $descr, $pipes); foreach($pipes as $f) stream_set_blocking($f, 0); //stream_set_write_buffer($pipes[0], 1*1024*1024); $br = 0; while ( ($line = fgets(STDIN, $max_buffer)) !== false){ $br = $br + strlen($line); $ret = fwrite($pipes[0], $line); if ($ret == false){ echo "error, buffer full?\n"; } $s = fgets($pipes[1], $max_buffer); printf("%12.3f | ", $br / 1024); process_output($s); } //stream_set_blocking($pipes[1], 1); fclose($pipes[0]); while (! feof($pipes[1]) ){ $s = fgets($pipes[1], $max_buffer); if ($s === false) continue; printf("%12s |", "end"); process_output($s); } fclose($pipes[1]); function process_output($s){ $s = trim($s); if (strlen($s) > 50) $s = substr($s, 0, 50) . " [crop]"; printf("%s\n", $s ? $s : "--none--"); } http://php.net/manual/en/function.stream-set-blocking.php

« previous php.notes (#192297) next »