почему ob_start () должен опережать session_start () для работы в PHP? - PullRequest
8 голосов
/ 20 сентября 2009

Не думаю, что это разумно.

Почему это на самом деле такое правило?

Ответы [ 5 ]

13 голосов
/ 20 сентября 2009

В " нормальном случае " я не думаю, что ob_start нужно вызывать до session_start - или наоборот.

Цитируя справочную страницу из session_start, хотя:

session_start () зарегистрирует внутренний обработчик вывода для перезаписи URL, когда Транс-Сид включен. Если пользователь использует ob_gzhandler или подобное с ob_start (), порядок обработчика вывода важно для правильного вывода. За Например, пользователь должен зарегистрироваться ob_gzhandler перед началом сессии.

Но это какой-то особый случай: дело здесь в том, что здесь важен порядок обработчиков вывода: если вы хотите, чтобы один обработчик изменял то, что делал другой, они должны выполняться в «правильном» режиме. заказ.


Как правило, если вы не используете такого рода обработчики (например, Apache и mod_deflate отлично справляются с работой, когда дело доходит до сжатия вывода) , единственное, что имеет значение является то, что заголовки не должны быть отправлены, прежде чем вы позвоните session_start (потому что, в зависимости от вашей конфигурации, session_start отправляет куки, которые передаются как заголовки HTTP) .

И заголовки отправляются, как только должен быть отправлен какой-либо фрагмент данных, т. Е. Как только есть какой-либо вывод, даже один пробел за пределами <?php ?> тегов:

Примечание: если вы используете куки-файлы сессий, вы должны позвонить session_start (), прежде чем что-либо выводится в браузер.

ob_start указывает, что PHP должен буферизовать данные:

Эта функция превратит выход буферизация на. Пока выходная буферизация не активен, выход не отправляется с сценарий (кроме заголовков), вместо выход сохраняется во внутреннем буфер.

Таким образом, вывод не отправляется до того, как вы на самом деле говорите: « отправьте данные ». Это означает, что заголовки не отправляются немедленно - это означает, что session_start можно вызвать позже, даже если он должен был быть выведен, если ob_start не использовался.


Надеюсь, это прояснит ситуацию ...

5 голосов
/ 20 сентября 2009

Если по умолчанию ваш output_buffering равен Off и вам не повезло отправить один байт данных обратно клиенту, тогда ваши HTTP заголовки уже отправлены. Что эффективно предотвращает передачу заголовка cookie клиенту session_start(). Вызывая ob_start(), вы включаете буферизацию и, следовательно, задерживаете отправку заголовков http.

0 голосов
/ 07 января 2015

session_start (); должен быть вызван перед отправкой любых заголовков. ob_start () на некоторое время подавит вывод, и вы можете нарушить это правило. Обычно ob_start () в верхней части - это быстрое решение, если вы отлаживаете что-то неизвестное; все ниже работает как положено (не так, как написано ;-)). Я предпочитаю использовать ob_start () позже для session_start ().

0 голосов
/ 29 марта 2014

session_start() зарегистрирует внутренний обработчик вывода для перезаписи URL, когда trans-sid включен. Если пользователь использует ob_gzhandler или как с ob_start(), порядок обработчика вывода важен для правильного вывода.

Например, пользователь должен зарегистрироваться ob_gzhandler до начала сеанса.

Но это какой-то особый случай. Дело в том, что здесь важен порядок обработчиков вывода. Если вы хотите, чтобы один обработчик изменил то, что сделал другой, они должны быть выполнены в «правильном» порядке.

Как правило, если вы не используете такого рода обработчики (например, Apache и mod_deflate отлично справляются со сжатием выходных данных), единственное, что имеет значение, это то, что заголовки не должны отправляться перед вами. звоните session_start (потому что, в зависимости от вашей конфигурации, session_start отправляет куки, которые передаются как заголовки HTTP).

И заголовки отправляются, как только должен быть отправлен какой-либо фрагмент данных, т. Е. Как только появляется какой-либо вывод, даже один пробел за пределами тегов <?php ?>:

Примечание: Если вы используете сеансы на основе файлов cookie, вы должны вызвать session_start(), прежде чем что-либо будет выведено в браузер.

ob_start указывает, что PHP должен буферизовать данные:

Эта функция включает буферизацию вывода. Пока активна буферизация вывода, из сценария не отправляются выходные данные (кроме заголовков), вместо этого выходные данные сохраняются во внутреннем буфере.

Таким образом, вывод не отправляется до того, как вы на самом деле говорите «отправьте данные». Это означает, что заголовки не отправляются немедленно - это означает, что session_start может быть вызван позже, даже если он должен был быть выведен, если ob_start не использовался.

0 голосов
/ 20 сентября 2009

session_start может потребоваться изменить заголовок HTTP, если установлены определенные параметры конфигурации. Например, session.use_cookies , для которого требуется установить / изменить поле заголовка Set-Cookie .

Изменение заголовка HTTP требует, чтобы не было никакого вывода, уже отправленного клиенту, поскольку заголовок HTTP отправляется непосредственно перед отправкой первого вывода.

Таким образом, вы либо гарантируете, что перед вызовом session_start ничего не выводится. Или вы используете элемент управления буферизацией вывода , чтобы буферизовать вывод, так что заголовок HTTP можно изменить, даже если он уже есть.

...