Я только что заметил что-то странное. Я думал, что, как говорится в руководстве PHP, session_start()
должен быть вызван до того, как какой-либо вывод будет отправлен в браузер:
Чтобы использовать сеансы на основе файлов cookie, необходимо вызывать session_start () перед выводом чего-либо в браузер.
Итак, просто для любопытства, я создал два сценария. Одним из них является 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
, отчеты журнала ошибок Apache:
[Tue Jan 03 11:57:21 2012] [error] [клиент 127.0.0.1] PHP Предупреждение: session_start (): Не удается отправить ограничитель кеша сеанса – заголовки уже отправлены в /var/www/sessions/write.php в строке 5 [Tue Jan 03 11:57:21 2012] [error] [client 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 [Tue Jan 03 11:57:21 2012] [ошибка] [клиент 127.0.0.1] PHP 2. session_start () /var/www/sessions/write.php : 5
Итак, мои вопросы: почему сессия написана правильно после того, как что-то echo
? Не сразу ли отправляется в браузер? И если да, значит ли это, что я могу начать сеанс в любом месте, до тех пор, пока я не называю flush()
раньше?
Чтобы использовать сеансы на основе файлов cookie, необходимо вызывать session_start () перед выводом чего-либо в браузер.
Это правда. Настройка cookie на стороне сервера (в отличие от настроек cookie JavaScript) работает, отправив HTTP-заголовок. Заголовки HTTP идут до фактического документа: после того, как вы начнете отправлять документ, больше нет места для заголовков.
В вашем случае происходит то, что эта строка:
echo 'foo';
… фактически не отправляет вывод в браузер. Вместо этого он добавляет некоторый вывод в очередь, которая будет отправлена позже. Интерпретатор PHP настроен на сохранение этого вывода до тех пор, пока не произойдет определенное событие (возможно, сценарии заканчиваются или очередь достигает определенного размера).
Директива output_buffering является вероятным подозреваемым.
Эта ошибка в session_start()
не означает, что у вас еще нет открытого сеанса. Этот метод пытается создать новый идентификатор сеанса, но вы уже можете его использовать. Попробуйте удалить все файлы cookie перед запуском этих скриптов.