Как выходной буфер может ухудшить производительность

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

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

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

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

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


person War Coder    schedule 08.02.2009    source источник
comment
Я очень благодарен вам всем за ваше время и положительный вклад в мой вопрос. Теперь я лучше понимаю вещи, особенно буфер вывода, который меня на некоторое время смутил. После всех постов я смог прийти с правильным подходом. Спасибо, ребята, вы все спасли меня от лишних размышлений.   -  person War Coder    schedule 09.02.2009


Ответы (4)


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

person David Z    schedule 08.02.2009
comment
+1 за указание на то, что данные не передаются в поток до вызова ob_flush (), что приведет к более медленному времени загрузки (но не обязательно к более медленному времени генерации). - person strager; 09.02.2009
comment
У меня вопрос по теме, могу я что с вами здесь ? - person Shafizadeh; 14.07.2015

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

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

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

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

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

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

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

person strager    schedule 08.02.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.

person Sergey Galashyn    schedule 08.02.2009
comment
спасибо за совет. должен был применить технику MVC с самого начала проекта. Помимо zend framework, какую другую платформу вы можете порекомендовать? я имею в виду тот, которым будет легко пользоваться. - person War Coder; 09.02.2009
comment
Фактически, большинство популярных фреймворков заставляют вас использовать MVC в той или иной форме. Также они дадут вам много других бонусов, например чистая структура приложения, ORM и т. д. Примеры: cakephp.org - это хорошо, но для начала использования требуется некоторое обучение, codeigniter.com кажется легче начать. - person Sergey Galashyn; 09.02.2009
comment
О, и самое главное, imo: даже если вы потратите некоторое время на перенос существующего кода разработчика в фреймворк - вы сохраните его в будущем. - person Sergey Galashyn; 09.02.2009

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

person SilentGhost    schedule 08.02.2009