How can an output buffer worsen performance
Я пишу сценарий PHP и где-то перед моим header()
Функция, которую я напечатал текст в браузере тем самым вызывая мой header()
Функция выдаст мне известную ошибку:
Предупреждение: невозможно изменить информацию заголовка - заголовки уже отправлены.
Теперь мой вопрос, у меня есть намерения использовать ob_start()
а также ob_flush()
до и после header()
функция. Но однажды я услышал, что что-то вроде выходного буфера может отрицательно повлиять на производительность приложения. Насколько это правда?
Или я должен просто придерживаться идеи печати функции Javascript для перенаправления страницы.
Спасибо за ваше время.
4 ответа
Использование буфера вывода требует, чтобы сервер сохранял весь вывод PHP в ОЗУ, поэтому, если это большая страница, вам придется использовать достаточное количество памяти - и серверу также придется ждать, пока вся страница не будет генерируется перед отправкой, что может вызвать небольшую задержку. Но кроме этого, я не думаю, что есть много недостатков в использовании выходного буфера. Для того, что вы хотите сделать, это, безусловно, разумное решение.
Мы должны забыть о малой эффективности, скажем, в 97% случаев: преждевременная оптимизация - корень всего зла.
Тестовое задание ob_start
и друзья, чтобы увидеть, если разница в производительности имеет значение. Если это так, ищите альтернативы.
Самый простой вариант - переместить header()
Позвоните до вашей печати.
Поскольку вы, вероятно, выполняете перенаправление с чем-то вроде:
header('Location: /new/location/');
Вы не должны ничего печатать до этого header()
звоните, потому что клиент не будет ничего делать с данными, которые вы напечатали, так или иначе (если я что-то упускаю в HTTP).
(Javascript не является хорошим вариантом для перенаправлений, и при этом meta
обновление, если вы не хотите обнаружить Javascript по какой-либо причине.)
Перемещение в 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; }
PS Этот код является частью фреймворка Fusebox.
Просто отвечая на ваше последнее замечание: вы можете перенаправить страницу в php используя header('Location: '.$url)
это должно идти перед любым другим выходом, очевидно, и рекомендуется следовать exit();