Подтвердить что ты не робот

PHP чтение shell_exec в прямом эфире

Я просто экспериментирую с PHP и shell_exec на моем Linux-сервере. Это действительно классная функция для использования, и я до сих пор наслаждаюсь ею. Есть ли способ просмотра живого вывода, который выполняется во время выполнения команды?

Например, если был запущен ping stackoverflow.com, когда он пинговал целевой адрес, каждый раз, когда он пингует, показывайте результаты с помощью PHP? Возможно ли это?

Мне бы очень хотелось увидеть текущее обновление буфера при его запуске. Возможно, это невозможно, но это было бы неплохо.

Это код, который я пытаюсь, и каждый раз, когда я его пробовал, он всегда отображает результаты после завершения команды.

<?php

  $cmd = 'ping -c 10 127.0.0.1';

  $output = shell_exec($cmd);

  echo "<pre>$output</pre>";

?>

Я попытался поместить часть echo в цикл, но все равно не повезло. У кого-нибудь есть предложения по поводу того, чтобы показать живое выступление на экране, а не ждать завершения команды?

Я пробовал exec, shell_exec, system и passthru. Каждый из них отображает контент после его завершения. Если я не использую неправильный синтаксис, или я неправильно настрою цикл.

4b9b3361

Ответ 1

Чтобы прочитать результат процесса, popen() - это путь. Ваш script будет работать параллельно с программой, и вы можете взаимодействовать с ним, читая и записывая его вывод/ввод, как если бы это был файл.

Но если вы просто хотите сбросить результат прямо к пользователю, вы можете вырезать дерьмо и использовать passthru():

echo '<pre>';
passthru($cmd);
echo '</pre>';

Теперь, если вы хотите отображать вывод во время выполнения программы, вы можете сделать это:

while (@ ob_end_flush()); // end all output buffers if any

$proc = popen($cmd, 'r');
echo '<pre>';
while (!feof($proc))
{
    echo fread($proc, 4096);
    @ flush();
}
echo '</pre>';

Этот код должен запускать команду и нажимать вывод прямо на конечного пользователя во время выполнения.

Ответ 2

Прежде всего, спасибо Havenard за ваш фрагмент - это очень помогло!

Немного модифицированная версия кода Havenard, которую я нашел полезным.

<?php
/**
 * Execute the given command by displaying console output live to the user.
 *  @param  string  cmd          :  command to be executed
 *  @return array   exit_status  :  exit status of the executed command
 *                  output       :  console output of the executed command
 */
function liveExecuteCommand($cmd)
{

    while (@ ob_end_flush()); // end all output buffers if any

    $proc = popen("$cmd 2>&1 ; echo Exit status : $?", 'r');

    $live_output     = "";
    $complete_output = "";

    while (!feof($proc))
    {
        $live_output     = fread($proc, 4096);
        $complete_output = $complete_output . $live_output;
        echo "$live_output";
        @ flush();
    }

    pclose($proc);

    // get exit status
    preg_match('/[0-9]+$/', $complete_output, $matches);

    // return exit status and intended output
    return array (
                    'exit_status'  => intval($matches[0]),
                    'output'       => str_replace("Exit status : " . $matches[0], '', $complete_output)
                 );
}
?>

Пример использования:

$result = liveExecuteCommand('ls -la');

if($result['exit_status'] === 0){
   // do something if command execution succeeds
} else {
    // do something on failure
}