PHP 在每次重新加载时创建新会话 [英] PHP creating new session with each reload

查看:63
本文介绍了PHP 在每次重新加载时创建新会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的网站,会话管理主要工作正常.会话的创建、保存和使用都没有问题.

For my website, session management mostly works ok. Sessions are created, saved and used later without problems.

但是当代码使用 session_start() 时,它总是创建新的、完全空的会话.下面有问题的代码.

But when the code is using session_start(), it always creates new, totally empty session. Code in question below.

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;

执行此脚本时,在每次重新加载时都会创建新会话.

When this script is executed, in every reload new session is created.

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

但只有其中一个会话在其中包含任何数据,并被应用程序使用.

But only the one of those sessions has any data inside it, and is used by application.

浏览器中的输出始终相同:87412d5882jr85gh5mkasmngg7,它是浏览器 cookie 中的 id 和/tmp 中已填充数据的会话 id.

Output in browser is always same: 87412d5882jr85gh5mkasmngg7, which is id in browser’s cookie and session id in /tmp that has data populated to it.

这种行为的原因是什么?这些空文件并不是什么大问题,但它们确实使/tmp(或会话目录)无缘无故地填充了大量内容.

What could be cause of this behaviour? Those empty files aren’t exactly huge problem, but they do make /tmp (or session dir) quite populated for no reason.

编辑 1:

看起来这是与服务器相关的问题,因为它适用于某些人.我的配置是带有 Apache 和 PHP 5.3.6 的 Gentoo Linux(32 位).

Looks like this is server related problem, since it works for some people. My configuration is Gentoo Linux (32 bit) with Apache and PHP 5.3.6.

如果我强制它创建新会话(比如删除我自己的 cookie),它会创建 两个 会话文件而不是一个.如果它重用旧的,它会仅"创建一个.

If I force it to create new session (like removing my own cookie), it creates two session files instead of one. If it reuses old one, it creates "only" one.

编辑 2:

会话配置,根据要求(所有配置行都带有 session.):

Session configuration, as requested (all config rows with 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 的会话.在那里,没有设置会话 cookie,它总是创建一个新会话.使用 session_id() 设置固定会话值时,完全停止创建新会话并改用旧会话.

Even more strangely, I tried to use sessions from CLI. There, where no session cookies are set, it always created one new session. When setting fixed session value with session_id() stopped new session creation altogether and used old session instead.

此行为与 Apache 相同,因此我开始怀疑这是 PHP 中的错误.如果使用 session_id() 专门设置了名称,并且正确使用了会话,则不会创建新会话.

This behaviour is identical with Apache, so I’m starting to suspect this is bug in PHP. No new sessions created if name specially set with session_id(), and session correctly used.

更荒谬的是,当我从 $_COOKIE["PHPSESSID"] 获取 phpsessid 并将其设置为 session_id() 时,它又开始创建新的(无用的空会话)会话.

Even more absurdly, when I took phpsessid from $_COOKIE["PHPSESSID"] and set that to session_id(), it started to create new (useless empty ones) sessions again.

编辑 4:

因为我写得不够清楚:只是有

Since I didn’t write it enough clearly: simply having

session_start()

由于单个参数会导致此问题发生,因此它不是特定于我的代码.

as single argument causes this problem to happen, it is not specific to my code.

推荐答案

Cookie 仅返回到设置它们的虚拟主机/路径.

Cookies are only returned to the vhost / path where they were set from.

由于您的路径是/",这意味着页面不是通过 $domain 请求的..".$tld;

Since your path is '/', that implies that the pages are not being requested via $domain . "." . $tld;

例如用户通过 www.example.com 请求页面

e.g. user requests page via www.example.com

cookie 是为 example.com 设置的

cookie is set for example.com

用户从 www.example.com 访问后续页面 - cookie 不在范围内.

user access subsequent page from www.example.com - the cookie is not in scope.

来自 RFC 2965

x.y.com 域匹配 .Y.com 但不匹配 Y.com.

x.y.com domain-matches .Y.com but not Y.com.

实际上,如果您继续阅读,规范确实说如果没有提供,用户代理应该在主机前面加上一个点,但是您进入了浏览器行为变化的领域.

Actually, if you read on, the spec does say that the user agent should prefix the host with a dot if none is supplied however you getting into the realm where browser behavuiour varies.

如果您只是返回带有与请求匹配的虚拟主机的 cookie,它将按预期工作.

If you simply return the cookie with a vhost matching the request it will work as expected.

这篇关于PHP 在每次重新加载时创建新会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆