php 7.3 无法打开隐藏会话(session_id() 设置id失败)
php 7.3 can not open hidden session (session_id() fails to set id)
我有一个 php 应用程序,它打开会话并像往常一样向浏览器发送适当的 cookie。
在脚本的某处我想关闭当前会话,默默地在后台打开一个新会话,从中获取一些值"background session",再次关闭它并恢复主会话(用户为其获取 cookie 的会话)。
在具有 PHP 7.0 的 Debian Stretch 中,以下最小示例非常有效,但现在在 PHP 7.3[=33 中=] (Debian Buster) 我收到几个警告,示例停止工作。
预期输出(如 PHP 7.0):
Main session closed now...<br>
Read data '10' and closed hidden session again...<br>
Main session resumed...<br>
实际输出(如PHP 7.3):
Main session closed now...<br>
Warning: session_id(): Cannot change session id when headers already sent
Warning: session_start(): Cannot start session when headers already sent
Read data '' and closed hidden session again...<br>
Warning: session_id(): Cannot change session id when headers already sent
Warning: session_start(): Cannot start session when headers already sent
Main session resumed...<br>
最小(非)工作示例:
$options=array('use_cookies'=>false, 'cache_limiter'=>'');
session_start();
$main_id=session_id();
$_SESSION["value"] = "xxx";
session_write_close();
echo "Main session closed now...<br>\n";
flush();
session_id("IdOfHiddenSession");
session_start($options);
$count=$_SESSION['count']++;
session_write_close();
echo "Read data '$count' and closed hidden session again...<br>\n";
flush();
session_id($main_id);
session_start($options);
echo "Main session resumed...<br>\n";
flush();
我该如何解决这个问题?
解决方案是在脚本启动时禁用所有会话 的会话 cookie ,而不是允许第一个 session_start()
的 cookie 并在随后的 session_start()
中禁用它们来电。
在这种情况下,您必须自己发送主会话的 cookie!
所以在脚本启动时执行:
ini_set("session.use_cookies", 0);
ini_set("session.use_only_cookies", 1);
并根据需要自行设置 cookie:
header("Set-Cookie: {$name}={$id}; path=/; secure; HttpOnly; SameSite=Strict");
问题的示例代码因此变为:
//do this *only* on script start before headers are sent
if(!headers_sent())
{
session_cache_limiter('');
ini_set("session.use_cookies", 0);
ini_set("session.use_only_cookies", 1);
}
session_start();
$main_id=session_id();
//send cookie
header("Set-Cookie: PHPSESSID={$main_id}; path=/; secure; HttpOnly; SameSite=Strict");
$_SESSION["value"] = "xxx";
session_write_close();
echo "Main session closed now...<br>\n";
flush();
session_id("IdOfHiddenSession");
session_start();
$count=$_SESSION['count']++;
session_write_close();
echo "Read data '$count' and closed hidden session again...<br>\n";
flush();
session_id($main_id);
session_start();
echo "Main session resumed...<br>\n";
flush();
我有一个 php 应用程序,它打开会话并像往常一样向浏览器发送适当的 cookie。
在脚本的某处我想关闭当前会话,默默地在后台打开一个新会话,从中获取一些值"background session",再次关闭它并恢复主会话(用户为其获取 cookie 的会话)。
在具有 PHP 7.0 的 Debian Stretch 中,以下最小示例非常有效,但现在在 PHP 7.3[=33 中=] (Debian Buster) 我收到几个警告,示例停止工作。
预期输出(如 PHP 7.0):
Main session closed now...<br>
Read data '10' and closed hidden session again...<br>
Main session resumed...<br>
实际输出(如PHP 7.3):
Main session closed now...<br>
Warning: session_id(): Cannot change session id when headers already sent
Warning: session_start(): Cannot start session when headers already sent
Read data '' and closed hidden session again...<br>
Warning: session_id(): Cannot change session id when headers already sent
Warning: session_start(): Cannot start session when headers already sent
Main session resumed...<br>
最小(非)工作示例:
$options=array('use_cookies'=>false, 'cache_limiter'=>'');
session_start();
$main_id=session_id();
$_SESSION["value"] = "xxx";
session_write_close();
echo "Main session closed now...<br>\n";
flush();
session_id("IdOfHiddenSession");
session_start($options);
$count=$_SESSION['count']++;
session_write_close();
echo "Read data '$count' and closed hidden session again...<br>\n";
flush();
session_id($main_id);
session_start($options);
echo "Main session resumed...<br>\n";
flush();
我该如何解决这个问题?
解决方案是在脚本启动时禁用所有会话 的会话 cookie ,而不是允许第一个 session_start()
的 cookie 并在随后的 session_start()
中禁用它们来电。
在这种情况下,您必须自己发送主会话的 cookie!
所以在脚本启动时执行:
ini_set("session.use_cookies", 0);
ini_set("session.use_only_cookies", 1);
并根据需要自行设置 cookie:
header("Set-Cookie: {$name}={$id}; path=/; secure; HttpOnly; SameSite=Strict");
问题的示例代码因此变为:
//do this *only* on script start before headers are sent
if(!headers_sent())
{
session_cache_limiter('');
ini_set("session.use_cookies", 0);
ini_set("session.use_only_cookies", 1);
}
session_start();
$main_id=session_id();
//send cookie
header("Set-Cookie: PHPSESSID={$main_id}; path=/; secure; HttpOnly; SameSite=Strict");
$_SESSION["value"] = "xxx";
session_write_close();
echo "Main session closed now...<br>\n";
flush();
session_id("IdOfHiddenSession");
session_start();
$count=$_SESSION['count']++;
session_write_close();
echo "Read data '$count' and closed hidden session again...<br>\n";
flush();
session_id($main_id);
session_start();
echo "Main session resumed...<br>\n";
flush();