PHP: Вывод результатов bash команды построчно в браузере


Для того что бы в коде php дернуть какую-то bash команду и вывести результаты, можно воспользоваться shell_exec(), но что делать если нужно видеть в реальном времени весь вывод по мере выполнения скрипта.

На днях задался вопросом, как выполнить скрипт или команду на linux сервере, которая генерирует много сообщений и наблюдать все сообщения в реальном времени в браузере.

Для начала объявим функцию:

function disable_ob() {
    // Выключить буферизацию вывода
    ini_set('output_buffering', 'off');

    // Выключаем сжатие вывода
    ini_set('zlib.output_compression', false);

    // Очистить буферы вывода
    ini_set('implicit_flush', true);
    ob_implicit_flush(true);

    while (ob_get_level() > 0) {
        // Получить текущие уровень вывода
        $level = ob_get_level();
        // Закончить буферизацию
        ob_end_clean();
        // Прерваться, если текущий уровень не изменился (новая строка не появилась)
        if (ob_get_level() == $level) break;
    }
    
    // Отключаем буферизацию и сжатие для Apache
    if (function_exists('apache_setenv')) {
        apache_setenv('no-gzip', '1');
        apache_setenv('dont-vary', '1');
    }
}

Она очищает буфер вывода после каждой новой строчки.

Дальше в коде вызываем эту функцию и объявляем команду, которую будем выполнять (я взял для примера ping):

disable_ob();
$command = 'ping 8.8.8.8';

Для того, что бы результат выглядел нормально, следующую конструкцию нужно обернуть тэгами <pre> ... </pre>

<?php
system($command);
?>

При открытии страницы вы увидите результаты пингов на DNS сервер 8.8.8.8 в реальном времени.

Share Button
(Visited 1 556 times, 2 visits today)

4 комментария на «“PHP: Вывод результатов bash команды построчно в браузере”»

  1. Отлично!!! А как быть например с побуквенным виводом? команда speedtest , например. надо что бы в браузере вывод отображался побуквенно ) реально ?
    $command = ‘/usr/local/bin/sudo /usr/local/bin/python2 /home/dmx/speedtest_cli.py —server 1746’;

    • Только что проверил на php 7.0.8 — все работает замечательно. Полный код ниже:

      <?php
      
      function disable_ob() {
          // Выключить буферизацию вывода
          ini_set('output_buffering', 'off');
      
          // Выключаем сжатие вывода
          ini_set('zlib.output_compression', false);
      
          // Очистить буферы вывода
          ini_set('implicit_flush', true);
          ob_implicit_flush(true);
      
          while (ob_get_level() > 0) {
              // Получить текущие уровень вывода
              $level = ob_get_level();
              // Закончить буферизацию
              ob_end_clean();
              // Прерваться, если текущий уровень не изменился (новая строка не появилась)
              if (ob_get_level() == $level) break;
          }
          
          // Отключаем буферизацию и сжатие для Apache
          if (function_exists('apache_setenv')) {
              apache_setenv('no-gzip', '1');
              apache_setenv('dont-vary', '1');
          }
      }
      
      disable_ob();
      $command = 'ping 8.8.8.8';
      ?>
      <pre>
      <?php
      system($command);
      ?>
      </pre>

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.