对于我的网站, session 管理大部分工作正常。 session 创建、保存和稍后使用都没有问题。
但是当代码使用 session_start() 时,它总是创建新的、完全空的 session 。下面有问题的代码。
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;
执行此脚本时,每次重新加载都会创建新 session 。
smar@ran ~> ls /tmp/sess_* | wc -l
10
smar@ran ~> ls /tmp/sess_* | wc -l
11
..
smar@ran ~> ls /tmp/sess_* | wc -l
17
但只有其中一个 session 中有任何数据,并被应用程序使用。
浏览器中的输出总是相同的:87412d5882jr85gh5mkasmngg7
,它是浏览器 cookie 中的 id 和/tmp 中填充数据的 session id。
这种行为可能是什么原因造成的?这些空文件并不是什么大问题,但它们确实使/tmp(或 session 目录)无缘无故地充满了。
编辑 1:
看起来这是与服务器相关的问题,因为它适用于某些人。我的配置是带有 Apache 和 PHP 5.3.6 的 Gentoo Linux(32 位)。
如果我强制它创建新 session (比如删除我自己的 cookie),它会创建两个 session 文件而不是一个。如果它重复使用旧的,它会创建“唯一”的。
编辑 2:
session 配置,按要求(所有带有 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 。在那里,没有设置 session cookie,它总是创建一个新 session 。当使用 session_id()
设置固定 session 值时,完全停止了新 session 的创建,而是使用旧 session 。
此行为与 Apache 相同,因此我开始怀疑这是 PHP 中的错误。如果使用 session_id()
专门设置名称,则不会创建新 session ,并且正确使用了 session 。
更荒谬的是,当我从 $_COOKIE["PHPSESSID"]
中获取 phpsessid 并将其设置为 session_id() 时,它又开始创建新的(无用的空 session ) session 。
编辑 4:
因为我写的不够清楚:简单的说
session_start()
由于单个参数会导致此问题发生,因此它并非特定于我的代码。
最佳答案
Cookie 仅返回到设置它们的虚拟主机/路径。
由于您的路径是“/”,这意味着页面不是通过 $domain 请求的。 “。” . $顶级域名;
例如用户通过 www.example.com 请求页面
cookie 是为 example.com 设置的
用户从 www.example.com 访问后续页面 - cookie 不在范围内。
来自 RFC 2965
x.y.com domain-matches .Y.com but not Y.com.
实际上,如果您继续阅读,该规范确实说如果没有提供用户代理应该在主机前加上一个点,但是您进入了浏览器行为不同的领域。
如果您简单地返回带有与请求匹配的 vhost 的 cookie,它将按预期工作。
关于PHP 在每次重新加载时创建新 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6815244/