Выходной буфер

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

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

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

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

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

Ответ 1

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

Ответ 2

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

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

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

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

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

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

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

Ответ 3

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

  • Разделить код на модель (обработка данных) и просмотр (вывод) (см. MVC). Это означает, что вы принимаете решение о перемещении даже перед отображением чего-либо. Я назвал этот путь предпочтительным.
  • Если вам действительно нужно показывать вывод (или другие отправленные заголовки), общий способ заключается в объединении 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.

Ответ 4

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