У меня есть команда, запускаемая с использованием exec (), которая возвращает значение из очень большого файла данных, но она должна выполняться миллионы раз. Чтобы избежать открытия файла каждый раз в цикле, я хочу перейти к proc_open
решение, где указатель файла создается один раз для эффективности, но не может решить, как это сделать.
Здесь exec
версия, которая работает, но медленно, предположительно, потому что она должна открывать файл в каждой итерации:
foreach ($locations as $location) {
$command = "gdallocationinfo -valonly -wgs84 datafile.img {$location['lon']} {$location['lat']}";
echo exec ($command);
}
Моя попытка proc_open
-Основанный код выглядит следующим образом:
$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']}\n");
fclose ($pipes[0]);
echo stream_get_contents ($pipes[1]);
fclose ($pipes[1]);
}
proc_close ($fp);
Это правильно получает первое значение, но затем генерирует ошибку для каждой последующей итерации:
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()
или что-нибудь еще.В следующем блоке вы закрываете каналы ввода и вывода процесса, и все же вы удивляетесь, когда вы больше не можете читать или писать?
foreach ($locations as $location) {
fwrite ($pipes[0], "{$location['lon']} {$location['lat']}\n");
fclose ($pipes[0]); // here
echo stream_get_contents ($pipes[1]);
fclose ($pipes[1]); // and here
}
Пытаться не делая это.
Других решений пока нет …