这可能听起来很显而易见:如果您在 php.ini 中将 session.auto_start 设置为“true”,则 session_name() 函数将没有本质影响。而显而易见的解释是会话已经启动,因此在执行 session_name() 函数之前(无论它在脚本中的什么位置)都无法更改,同样的原因,session_name 需要在文档中记录的 session_start() 之前调用。
我知道这真的不是什么大问题。但在弄清楚这一点之前,我遇到了相当大的困难,希望这对像我这样的人有所帮助。
(PHP 4, PHP 5, PHP 7, PHP 8)
session_name — 获取和/或设置当前会话名称
session_name() 返回当前会话的名称。如果提供了 name
,则 session_name() 将更新会话名称并返回旧的会话名称。
如果提供了新的会话 name
,则 session_name() 会修改 HTTP Cookie(并在启用 session.use_trans_sid 时输出内容)。发送 HTTP Cookie 后,调用 session_name() 会引发 E_WARNING
。为了使会话正常工作,必须在 session_start() 之前调用 session_name()。
会话名称在请求启动时重置为存储在 session.name
中的默认值。因此,您需要为每个请求(并在调用 session_start() 之前)调用 session_name()。
name
会话名称引用会话的名称,该名称用于 Cookie 和 URL(例如 PHPSESSID
)。它应该只包含字母数字字符;它应该简短且具有描述性(即对于启用了 Cookie 警告的用户)。如果指定了 name
且不为 null
,则当前会话的名称将更改为其值。
会话名称不能仅由数字组成,必须至少包含一个字母。否则,每次都会生成新的会话 ID。
返回当前会话的名称。如果给出了 name
并且函数更新了会话名称,则返回旧的会话名称,或者在失败时返回 false
。
版本 | 描述 |
---|---|
8.0.0 |
name 现在可以为空。 |
7.2.0 | session_name() 检查会话状态,以前它只检查 Cookie 状态。因此,旧的 session_name() 允许在 session_start() 之后调用 session_name(),这可能会导致 PHP 崩溃并可能导致行为异常。 |
示例 #1 session_name() 示例
<?php
/* 将会话名称设置为 WebsiteID */
$previous_name = session_name("WebsiteID");
echo "之前的会话名称是 $previous_name<br />";
?>
这可能听起来很显而易见:如果您在 php.ini 中将 session.auto_start 设置为“true”,则 session_name() 函数将没有本质影响。而显而易见的解释是会话已经启动,因此在执行 session_name() 函数之前(无论它在脚本中的什么位置)都无法更改,同样的原因,session_name 需要在文档中记录的 session_start() 之前调用。
我知道这真的不是什么大问题。但在弄清楚这一点之前,我遇到了相当大的困难,希望这对像我这样的人有所帮助。
记住,孩子们——如果您想使用 session_set_cookie_params() 来更改会话超时,则**必须**首先使用 session_name()。否则它将无法工作,不会给出任何错误,并且文档中(我见过的任何文档)都不会解释原因。
感谢 bildungsroman.com 的 brandan 在 session_set_cookie_params() 下留下了一条注释解释了这一点,否则我可能仍然对此束手无策。
对于那些想知道的人,此函数开销很大!
在一个以 0.0025 秒的持续时间执行的脚本中,仅仅使用 session_name("foo") 就将我的执行时间提高到大约 0.09 秒。通过简单地牺牲 session_name("foo"),我将脚本速度提高了大约 0.09 秒。
正如 Joseph Dalrymple 所说,添加 session_name 会稍微降低执行时间。
但是,我观察到它减少了请求之间的波动。
我的脚本上的请求在 0.045 秒和 0.022 秒之间波动。使用 session_name("myapp"),它变为 0.050 秒和 0.045 秒。没什么大不了的,但这是一个需要注意的点。
对于在设置名称时遇到问题的人,当 session.auto_start 设置为 1 时,您需要在 php.ini 中设置 session.name!
希望这不会超出 php.net 的注释范围。
session_name('name') 必须在 session_start() 之前设置,因为前者更改 ini 设置,而后者读取它们。出于同样的原因,session_set_cookie_params($options) 也必须在 session_start() 之前设置。
我发现最好执行以下操作。
function is_session_started()
{
if (php_sapi_name() === 'cli')
return false;
if (version_compare(phpversion(), '5.4.0', '>='))
return session_status() === PHP_SESSION_ACTIVE;
return session_id() !== '';
}
if (!is_session_started()) {
session_name($session_name);
session_set_cookie_params($cookie_options);
session_start();
}
session_name() 获取和/或设置当前会话名称的描述在技术上是错误的。它除了处理最初由 php.ini 文件中的 session.name 值提供的 value 之外什么也不做。
因此:-
$name = session_name();
在功能上等效于
$name = ini_get('session.name');
和
session_name('newname);
在功能上等效于
ini_set('session.name','newname');
这也意味着
$old_name = session_name('newname');
在功能上等效于
$old_name = ini_set('session.name','newname');
session.name 的当前值在调用 session_start() 之前不会附加到任何会话中。一旦 session_start() 使用 session.name 在 cookie 数据中查找 session_id(),则名称变得无关紧要,因为对会话数据的后续所有操作都以 session_id() 为键。
请注意,在会话当前处于活动状态时更改 session.name 不会更新任何会话 cookie 中的名称。新名称直到下次调用 session_start() 才会生效,这需要关闭使用 session.name 的先前值创建的当前会话。
最近修改了描述,其中包含语句“当提供新的会话名称时,session_name() 会修改 HTTP cookie”。这是不正确的,因为 session_name() 从未修改任何 cookie 数据。session.name 的更改直到调用 session_start() 才会生效,并且是 session_start() 在 cookie 不存在时创建 cookie 的。
有关详细信息,请参阅以下错误报告:https://bugs.php.net/bug.php?id=76413
始终尝试将会话名称属性的前缀设置为 `__Host-` 或 `__Secure-`,以利用浏览器改进的安全功能。请参阅 https://mdn.org.cn/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes
此外,如果启用了自动会话,则必须在配置中(php.ini、htaccess 等)的 session.name 中设置此名称。