Захватить результаты из php exec (), пока команда еще работает? - PullRequest
4 голосов
/ 09 октября 2011

Когда я запускаю exec из PHP, примерно так:

$result = exec('command');

Результаты этого будут сохранены в $result. Но в моем текущем случае моя команда может занять несколько минут и выводить результаты во время работы. Есть ли способ получить вывод во время его работы? Я знаю, что метод passthru будет выводить результаты в браузер, но я на самом деле хочу его напрямую.

Ответы [ 5 ]

5 голосов
/ 09 октября 2011

Вы должны взглянуть на proc_open

После того, как выходной поток будет неблокирующим (с stream_set_blocking), вы сможете читать с него в любое время, не блокируя свой PHP-код.

-Edit- Если вы используете

$result = exec('command > /path/to/file &');

Он будет работать в фоновом режиме, и вы можете прочитать вывод в / path / to / file

4 голосов
/ 02 июля 2013

Возможно, не самый лучший способ сделать это (но у меня получилось):

<?php

$cmd = "ping 127.0.0.1 -c 5"; //example command

$descriptorspec = array(
    0 => array("pipe", "r"), 
    1 => array("pipe", "w"), 
    2 => array("pipe", "a")
);

$pipes = array();

$process = proc_open($cmd, $descriptorspec, $pipes, null, null);

echo "Start process:\n";

$str = "";

if(is_resource($process)) {
    do {
        $curStr = fgets($pipes[1]);  //will wait for a end of line
        echo $curStr;
        $str .= $curStr;

        $arr = proc_get_status($process);

    }while($arr['running']);
}else{
    echo "Unable to start process\n";
}

fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

echo "\n\n\nDone\n";

echo "Result is:\n----\n".$str."\n----\n";

?>
3 голосов
/ 09 октября 2011

укажите второй аргумент

exec('command', $result);

Если присутствует выходной аргумент, то указанный массив будет заполняться каждой строкой вывода команды.Конечные пробелы, такие как \ n, не включены в этот массив.Обратите внимание, что если массив уже содержит некоторые элементы, exec () добавится в конец массива.Если вы не хотите, чтобы функция добавляла элементы, вызовите unset () для массива перед передачей его в exec ().

0 голосов
/ 14 февраля 2015

Для кого бы это ни помогло, я использовал ответ Эдди и изменил его для своих целей (вывод файла дампа MySQL без заполнения оперативной памяти сервера)

$dumpCommand = "mysqldump --skip-lock-tables -u $dbuser -p$dbpasswd $dbname";
$dumpFileName = 'backup_'.$dbname.'-'.date('Ymd-Hi').'.sql';

$descriptorSpec = array(
    0 => array("pipe", "r"), 
    1 => array("pipe", "w"), 
    2 => array("pipe", "a")
);

$pipes = array();

$process = proc_open($dumpCommand, $descriptorSpec, $pipes, null, null);

if(!is_resource($process)) {
    die('Unable to start process');
}

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$dumpFileName.'"');

do {
    echo fgets($pipes[1]); // Will wait for EOL
    $arrStatus = proc_get_status($process);
} while($arrStatus['running']);

fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
0 голосов
/ 09 октября 2011

Может быть возможно добиться того, что вам нужно, используя passthru() в сочетании с буферизацией вывода .Не уверен, однако.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...