PHP создает новую сессию с каждой перезагрузкой - PullRequest
7 голосов
/ 25 июля 2011

Для моего сайта управление сессиями в основном работает нормально. Сессии создаются, сохраняются и используются позже без проблем.

Но когда код использует session_start (), он всегда создает новый, совершенно пустой сеанс. Код под вопросом ниже.

header('Content-Type: text/html; charset=UTF-8');

$main_domain = $_SERVER["HTTP_HOST"];
$expld = explode('.', $main_domain);

if(count($expld) > 2) {
   $tld = array_pop($expld);
   $domain = array_pop($expld);
   $main_domain = $domain . "." . $tld;
}

session_set_cookie_params (0, '/', $main_domain);
session_name('sid');
session_start();
echo session_id();
exit;

Когда этот скрипт выполняется, при каждой перезагрузке создается новый сеанс.

smar@ran ~> ls /tmp/sess_* | wc -l
10
smar@ran ~> ls /tmp/sess_* | wc -l
11
..
smar@ran ~> ls /tmp/sess_* | wc -l
17

Но только один из этих сеансов имеет какие-либо данные внутри и используется приложением.

Вывод в браузере всегда один и тот же: 87412d5882jr85gh5mkasmngg7, который является идентификатором в файле cookie браузера и идентификатором сеанса в / tmp, в котором хранятся данные.

Что может быть причиной такого поведения? Эти пустые файлы не являются огромной проблемой, но они делают make / tmp (или каталог сеанса) достаточно заполненным без причины.

РЕДАКТИРОВАТЬ 1:

Похоже, это проблема, связанная с сервером, поскольку она работает для некоторых людей. Моя конфигурация - Gentoo Linux (32 бит) с Apache и PHP 5.3.6.

Если я заставлю его создать новый сеанс (например, удалить мой собственный файл cookie), он создаст два файла сеанса вместо одного. Если он повторно использует старый, он создает «только один».

РЕДАКТИРОВАТЬ 2:

Конфигурация сеанса, согласно запросу (все строки конфигурации с session.):

session.save_handler = files
session.save_path = "/tmp"
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.bug_compat_42 = On
session.bug_compat_warn = On
session.referer_check =
session.entropy_length = 0
session.entropy_file =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 5

РЕДАКТИРОВАТЬ 3:

Еще более странно, я пытался использовать сеансы из CLI. Там, где не установлены сеансовые куки, он всегда создает один новый сеанс. При установке фиксированного значения сеанса с помощью session_id() полностью прекратилось создание нового сеанса и вместо него использовался старый сеанс.

Это поведение идентично Apache, поэтому я начинаю подозревать, что это ошибка в PHP. Новые сеансы не создаются, если имя специально установлено с session_id(), и сеанс правильно используется.

Еще более нелепо, когда я взял phpsessid из $_COOKIE["PHPSESSID"] и установил его на session_id (), он снова начал создавать новые (бесполезные пустые) сессии.

РЕДАКТИРОВАТЬ 4:

Так как я написал недостаточно четко: просто

session_start()

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

Ответы [ 5 ]

2 голосов
/ 25 июля 2011

Файлы cookie возвращаются только в vhost / path, где они были установлены.

Поскольку ваш путь - '/', это означает, что страницы не запрашиваются через $ domain."",$ tld;

например, страница запросов пользователя через www.example.com

cookie настроен для example.com

доступ пользователя к следующей странице с www.example.com -cookie не входит в область действия.

С RFC 2965

Соответствует домену xycom .Y.com, но не Y.com.

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

Если вы просто вернетесьcookie с vhost, совпадающим с запросом, он будет работать как положено.

0 голосов
/ 18 февраля 2014

Я бы не хотел быть в грязи, но вы проверяли, что /tmp доступен для чтения и записи в PHP (в большинстве случаев это означает пользователя www-data)? Если нет, переместите место сохранения сеанса в место, в которое можно записать.

0 голосов
/ 13 декабря 2012

Это не совсем о первоначальной причине, но разрешение точно такое же: новые идентификаторы сеанса определяются с каждой перезагрузкой.

В этом случае неисправность была Varnish, которая была настроена на установку каждого запроса напроходной режим (return (pass)) вместо кэширования всего.Как следствие, каждый запрос поступал в бэкэнд, где каждый раз вызывался метод session_start ().

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

Это большеошибка в распознавании ошибки в этом случае, которая возникла как множество ненужных созданных сеансов.Они не были бы созданы в первую очередь, если бы кэширование было включено в первую очередь.

Существует также другой способ создания этих сеансов: у браузера вообще не приниматься файлы cookie.Глупая причина, я знаю, но это случается ...

Для первоначальной проблемы я не оступился с тех пор, как отошел от оригинальной машины разработки.

0 голосов
/ 11 июня 2012

Я думаю, что Powtac в некотором смысле прав, но session_start(); должна быть вашей первой операцией, которую вы делаете, даже до header('Content-Type: text/html; charset=UTF-8');

0 голосов
/ 25 июля 2011

Используйте session_start() в качестве первой команды сеанса, прежде чем все другие session_*() методы!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...