2012-01-03 2 views
3

Я только что заметил что-то странное. Я подумал, что, как говорит руководство РНР, session_start() должен вызываться до любого вывода отправляется в браузер:session_start() работает после отправки вывода

Чтобы использовать куки на основе сеансов, session_start() должен быть вызван до outputing ничего в браузере.

Итак, просто для любопытства, я создал два сценария. Одним из них является write.php:

<?php 
echo 'foo'; 

session_start(); 
$_SESSION['bar'] = 'baz'; 
?> 

И другая является read.php:

<?php 
echo 'foo'; 

session_start(); 
var_dump($_SESSION['bar']); 
?> 

И удивительно, что сессия записывается и читается даже после того, как echo ИНГ Foo.

Однако, если добавить вызов flush() после echo с, сообщает журнал ошибок апача:

[Вт 3 января 11:57:21 2012] [ошибка] [клиент 127.0.0.1] PHP Предупреждение: session_start(): Не удается отправить ограничитель кеша сеанса - заголовки уже отправлены в /var/www/sessions/write.php в строке 5 [Tue Jan 03 11:57:21 2012] [ошибка] [клиент 127.0.0.1] PHP Stack trace: [Tue Jan 03 11:57:21 2012] [ошибка] [клиент 127.0.0.1] PHP 1. {main}() /var/www/sessions/write.php:0 [Вт Янв 03 11:57:21 2012] [ошибка] [клиент 127.0.0.1] PHP 2. session_start() /var/www/sessions/write.php:5 ​​

Итак, мои вопросы: почему сессия написана правильно после echo Что-то? Не сразу ли отправляется в браузер? И если да, значит ли это, что я могу начать сеанс в любом месте, до тех пор, пока я не звоню flush()?

+5

[Google «PHP-буферизация вывода»] (http://www.google.com/search?q=php+output+buffering) – DaveRandom

ответ

6

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

Это правда. Настройка cookie на стороне сервера (в отличие от настроек cookie JavaScript) работает, отправив HTTP-заголовок. Заголовки HTTP идут до фактического документа: после того, как вы начнете отправлять документ, больше нет места для заголовков.

В вашем случае, то, что происходит в том, что эту линию:

echo 'foo'; 

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

Директива output_buffering является вероятным подозреваемым.

+0

'' 'output_buffering''' установлен в' '' 4096''', а '' 'implicit_flush'''' '' Off'''. Таким образом, чтобы мои скрипты больше не работали, даже не называя '' 'flush()' '', я должен включить '' 'implicit_flush''' и установить' '' output_buffering''' '' '0 '' ', правильно? –

0

Эта ошибка в session_start() не означает, что у вас еще нет открытой сессии. Этот метод пытается создать новый идентификатор сеанса, но вы уже можете его использовать. Попробуйте удалить все файлы cookie перед запуском этих скриптов.

+0

Я сделал. Я удалил '' 'PHPSESSID''', а затем снова запустил сценарии, и произошло то же самое: если я добавлю' '' flush() '' 'после' '' echo''', ** read.php ** отображает ** NULL **, если я этого не сделаю, он отображает ** baz **, как ожидалось. –

+0

вы должны иметь буферизацию outbut, включенную в настройках php. – kaz

Смежные вопросы