почему ob_start () должен опережать session_start () для работы в PHP?

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

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

Solutions Collecting From Web of "почему ob_start () должен опережать session_start () для работы в PHP?"

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

Однако, указав страницу руководства session_start :

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

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

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

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

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

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

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

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

Надеюсь, это сделает вещи немного более ясными …

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

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

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

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

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

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

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

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

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

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

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

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

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

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