note 110755 modified in function.stream-set-blocking by danbrown
| From: | danbrown@php.net | 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