在某些情况下,您需要在会话名称中实施支持句点的解决方案。例如,我遇到了类似的问题。我必须创建一个 PHP 页面来模拟 ASP 页面的确切行为,以与客户的外部硬编码前端保持兼容。在给定的请求标头ASP.NET_SessionId
中存在 cookie 名称。
如果其他人遇到类似的限制,这里有一个解决方法。
经过一些研究和测试,我得出了结果,错误行为的原因是,$_COOKIE
当 cookie 名称中有特殊字符时,它不包含正确的键。
<?php session_start (['name' => 'ASP.NET_SessionId']); ?>
<html>
<head><title></title><meta charset="UTF-8"></head>
<body>
<pre><?php
//echo implode("\n", apache_request_headers());
foreach (apache_request_headers() as $header => $value)
echo "$header: $value" . PHP_EOL;
echo "\n";
var_dump($_COOKIE);
?></pre>
</body>
</html>
输出:
Host: example.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: ASP.NET_SessionId=31run6vlfk69j0ni9l02fad82u
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
array(1) {
["ASP_NET_SessionId"]=>
string(26) "31run6vlfk69j0ni9l02fad82u"
}
您会在第二个请求中获得类似的输出。会话 ID 随每个请求而变化,因为默认会话处理程序无法正确识别会话名称。不幸的是,既没有抛出错误,也没有记录任何通知。
SessionHandlerInterface
当会话已经存在时,我们可以通过实现并获取原始 cookie 数据来覆盖给定的预先计算的会话 id来编写我们自己的会话处理程序。
但是,我选择了一个快速的解决方法。默认会话处理程序显然只是评估$_COOKIES
变量(或依赖于相同的生成算法)。实际上$_COOKIE
变量是一个关联数组,它可以有任意字符串,包括空格、句点等作为键。我们也可以$_COOKIE
在运行时覆盖变量。
<?php
$raw_cookies = apache_request_headers()['Cookie'];
$cookies = preg_split('/;\s*/', $raw_cookies);
$_COOKIE = [];
foreach ($cookies as $cookie)
{
list($k, $v) = explode('=', $cookie, 2);
$_COOKIE[$k] = $v;
}
session_start (['name' => 'ASP.NET_SessionId']);
?>
<html>
<head><title></title><meta charset="UTF-8"></head>
<body>
<pre><?php var_dump($_COOKIE); ?></pre>
</body>
</html>
输出:
array(1) {
["ASP.NET_SessionId"]=>
string(26) "jqf97quci4sh6k0n4p59b3d18n"
}
现在会话 id 保持稳定,并且$_SESSION
在每次请求后恢复值。
请注意,这apache_request_headers()
是支持 Apache Web 服务器的特定功能。还应该有支持替代服务器的功能。
编辑:在我的 Apache 服务器上,我也在$_SERVER[HTTP_COOKIE']
.