I have a command run using exec() which returns a value from within a very large data file, but it has to run millions of times. In order to avoid having the file opened each time in a loop, I want to move to a proc_open
-based solution, where the file pointer is created once for efficiency, but can't work out how to do this.
Here is the exec
-based version, which works but is slow, presumably because it has to open the file in each iteration:
foreach ($locations as $location) {
$command = "gdallocationinfo -valonly -wgs84 datafile.img {$location['lon']} {$location['lat']}";
echo exec ($command);
}
My attempt at a proc_open
-based code is as follows:
$descriptorspec = array (
0 => array ('pipe', 'r'), // stdin - pipe that the child will read from
1 => array ('pipe', 'w'), // stdout - pipe that the child will write to
// 2 => array ('file', '/tmp/errors.txt', 'a'), // stderr - file to write to
);
$command = "gdallocationinfo -valonly -wgs84 datafile.img";
$fp = proc_open ($command, $descriptorspec, $pipes);
foreach ($locations as $location) {
fwrite ($pipes[0], "{$location['lon']} {$location['lat']}
");
fclose ($pipes[0]);
echo stream_get_contents ($pipes[1]);
fclose ($pipes[1]);
}
proc_close ($fp);
This correctly gets the first value, but then generates an error for each subsequent iteration:
3.3904595375061
Warning: fwrite(): 6 is not a valid stream resource in file.php on line 11
Warning: fclose(): 6 is not a valid stream resource in file.php on line 12
Warning: stream_get_contents(): 7 is not a valid stream resource in file.php on line 13
Warning: fclose(): 7 is not a valid stream resource in file.php on line 14
Warning: fwrite(): 6 is not a valid stream resource in file.php on line 11
...
proc_open()
or anything else.In the following block you're closing both the input and output pipes of the process, and yet you're surprised when you're no longer able to read or write?
foreach ($locations as $location) {
fwrite ($pipes[0], "{$location['lon']} {$location['lat']}
");
fclose ($pipes[0]); // here
echo stream_get_contents ($pipes[1]);
fclose ($pipes[1]); // and here
}
Try not doing that.