PHP, Nginx, отключение буферизации

В некоторых случаях требуется чтобы скрипт на PHP выводил свои данные в браузер без буфферизации, непосредственно после команд echo или print_r.
Например, при написании долгоиграющего скрипта, который должен быть запущен при помощью pdem, чтобы выводить из скрипта прогресс выполнения и прочие данные в сервер pdem, понадобится отключить буферизацию.
Как выяснилось, в интернете есть целая куча разных рекомендаций и решений вопроса отключения буферизации, который пришлось объединить в одно целое, чтобы добиться цели. В моём случае, буфферизация Nginx и Yii вставляли палки в колёса.
Здесь я представляю данное решение.

/**
* Перейти в режим отключённой буферизации
* @param boolean $closeSession Сохранить и закрыть сессию. 
*                              Нужно, если скрипт долгоиграющий, и вы не хотите, 
*                              чтобы, пока он работает, у вас заклинивало весь остальной сайт.
*/
function switchOffBuffering($closeSession=true)
{    
    if ($closeSession)
    {
        //Сохраним и закроем сессию, если надо.
        session_write_close();
    }
    //Сообщим серверу и браузеру, что кэшировать выдачу не надо.
    header("Cache-Control: no-cache, must-revalidate");
    //Сообщим серверу Nginx, что буферизировать не надо
    header('X-Accel-Buffering: no');
    //Включим автоматический сброс буфера при каждом выводе
    ob_implicit_flush(true);
    //Сбросим все уровни буферов PHP, созданные на данный момент.
    while (ob_get_level() > 0) {
        ob_end_flush();
    }
}

4 комментария

    • Ответить mihanentalpo |

      На здоровье. Я как раз заглянул в этот пост и увидел что у меня неправильно преобразовались кавычки и знак «>» в html entities, поправил.

  • Ответить Михаил |

    Уже несколько дней занимался одной функцией. Не мог дальше js писать после реализации php, вечная беда err_connection_reset. Методом проб и ошибок определил что проблема вылетает с самого nginx. Начал искать что и как и пришёл сюда статью почитать, в итоге отключил буферизацию именно на этот скрипт и больше никакой ошибки!!! Жаль что быстрее не нашёл. Статья очень помогла!

    • Ответить mihanentalpo |

      Повезло, что это помогло. err_connection_reset может иметь огромное количество причин, вплоть до кривой прошивки домашнего роутера. Спасибо за отзыв 🙂

Оставить комментарий