Как выходной буфер может ухудшить производительность - PullRequest
3 голосов
/ 08 февраля 2009

Я пишу скрипт php и где-то перед своей функцией header() я распечатал текст в браузере, в результате чего моя функция header() выдает мне известную ошибку:

Предупреждение: невозможно изменить информацию заголовка - заголовки уже отправлены.

Теперь мой вопрос: у меня есть намерения использовать ob_start() и ob_flush() до и после функции header(). Но однажды я слышал, что что-то вроде выходного буфера может отрицательно повлиять на производительность приложения. Насколько это правда?

Или я должен просто придерживаться идеи печати функции Javascript для перенаправления страницы.

Спасибо за ваше время.

Ответы [ 4 ]

5 голосов
/ 08 февраля 2009

Мы должны забыть о малой эффективности, скажем, в 97% случаев: преждевременная оптимизация - корень всех зол.

Тест ob_start и друзей, чтобы увидеть, если разница в производительности имеет значение. Если это так, ищите альтернативы.

Самый простой вариант - переместить вызов header() перед печатью.

Поскольку вы, вероятно, выполняете перенаправление с чем-то вроде:

header('Location: /new/location/');

Вы не должны ничего печатать перед этим вызовом header(), потому что клиент ничего не будет делать с данными, которые вы напечатали в любом случае (если только что-то не хватает в HTTP).

(Javascript не является хорошим вариантом для перенаправлений, и при этом meta не обновляет, если вы по какой-то причине не хотите обнаруживать Javascript.)

4 голосов
/ 08 февраля 2009

Использование выходного буфера требует, чтобы сервер сохранял весь вывод PHP в ОЗУ, поэтому, если это большая страница, вам придется использовать достаточное количество памяти - и серверу также придется ждать, пока перед отправкой создается вся страница, что может привести к небольшой задержке. Но кроме этого, я не думаю, что есть большой недостаток в использовании выходного буфера. Для того, что вы хотите сделать, это, безусловно, разумное решение.

2 голосов
/ 09 февраля 2009

Перемещение в PHP-коде после вывода может говорить о плохом дизайне приложения. Но я не знаю вашей ситуации и могу предложить два возможных пути.

  1. Разделение кода на модель (обработка данных) и просмотр (вывод) (см. MVC ). Это означает, что вы принимаете решение о перемещении еще до того, как что-либо отобразите. Я бы назвал этот путь предпочтительным.
  2. Если вам действительно необходимо показать выходные данные (или другие отправленные заголовки), наиболее распространенным способом является объединение JS и HTML (в noscript):

    if (headers_sent()) {
        print('<script type="text/javascript">( document.location.replace ) ? document.location.replace("'.$location.'") : document.location.href = "'.$location.'";</script>'."\n".'<noscript><meta http-equiv="Refresh" content="0;URL='.$location.'" /></noscript>');
    } else {
        header('Location: '.$location);
        exit;
    }
    

P.S. Этот код является частью инфраструктуры Fusebox.

0 голосов
/ 08 февраля 2009

просто отвечая на ваше последнее замечание: вы можете перенаправить страницу в php, используя header('Location: '.$url), она должна идти перед любым другим выводом, и после нее рекомендуется следовать exit();

...