Вместо stream_get_contents
вы можете использовать fread
, чтобы получить более точный контроль над тем, что делает ваш код.Это в сочетании с stream_set_timeout может дать вам то, что вы ищете.
Я бросил что-то вместе, чтобы продемонстрировать, что, как я думал, может сработать - этот код полностью не проверен и не имеетгарантии, но может отправить вас в правильном направлении.;)
function execute($cmd,$stdin=null,$timeout=-1){
$proc=proc_open(
$cmd,
array(array('pipe','r'),array('pipe','w'),array('pipe','w')),
$pipes=null
);
fwrite($pipes[0],$stdin); fclose($pipes[0]);
stream_set_timeout($pipes[1], 0);
stream_set_timeout($pipes[2], 0);
$stdout = '';
$start = microtime();
while ($data = fread($pipes[1], 4096))
{
$meta = stream_get_meta_data($pipes[1]);
if (microtime()-$start>$timeout) break;
if ($meta['timed_out']) continue;
$stdout .= $data;
}
$return = proc_close($proc);
$stdout .= stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
return array(
'stdout' => $stdout,
'stderr' => $stderr,
'return' => $return
);
}