最近,我在日志中收到以下错误:
PHP Warning: session_start(): The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in [...] on line [..]
PHP Warning: Unknown: The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in Unknown on line 0
PHP Warning: Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/var/lib/php5) in Unknown on line 0
this previous question的答案足以检测和转移这样的场景,这样就不会产生错误,但我对最优雅的<感兴趣< EM>恢复;也就是说,以有效的新(空)会话结束。
首先,对检测和检测进行了一些改进。转移代码在上一个问题中,现在已有六年了:
现在,会话更有可能通过cookie完全处理。我的php.ini中的session.use_only_cookies
标志已启用,由于我不记得更改它,我认为这是默认值。
有效会话ID中使用了哪些字符,以及这些字符中有多少字符取决于php.ini中的session.hash_function
和session.hash_bits_per_character
值。我的值分别是0和5,除非我弄错了,这意味着我自己的会话ID应该与正则表达式/^[a-v0-9]{26}$/
匹配。我认为这些也是默认值。
可以使用php.ini中的session.name
自定义用于存储会话的cookie的名称。始终可以使用session_name()
函数检索正确的值。
鉴于这些,最优雅的转移方式(可能)如下:
function my_session_start() {
if (!isset($_COOKIE[session_name()]) || preg_match('/^[a-v0-9]{26}$/', $_COOKIE[session_name()]) !== 0) {
return session_start(); // since 5.3, returns TRUE on success, FALSE on failure.
}
else {
return false;
}
}
至于恢复(将替换return false;
块中的else
),one answer to the previous question建议如下:
session_id(uniqid());
session_start();
session_regenerate_id();
然而,我担心这种恢复方式只收到两份赞成票而没有评论,但未得到充分的审查。
this question的答案表明内部session_start()
函数直接依赖 值$_COOKIE[session_name()]
,而不是该值的其他内部表示。是这样的吗?如果是这样,具有检测和恢复功能的my_session_start()
函数可以如下所示:
function my_session_start() {
if (isset($_COOKIE[session_name()]) && preg_match('/^[a-v0-9]{26}$/', $_COOKIE[session_name()]) === 0) {
unset($_COOKIE[session_name()]);
}
return session_start();
}
答案 0 :(得分:3)
我只在$_COOKIE['PHPSESSID'] === ''
时才看到这种情况发生。当有人使用Firebug来清除cookie&#34;时会发生这种情况。我只想处理这个具体情况;如果会话ID以其他方式无效,我想收到警告。处理我的具体用例很简单:
$session_name = session_name();
if (isset($_COOKIE[$session_name]) and empty($_COOKIE[$session_name])) {
// This happens when someone does "clear cookie" in Firebug; it causes session_start()
// to trigger a warning. session_start() relies on $_COOKIE[$session_name], thus:
unset($_COOKIE[$session_name]);
}
session_start();
出于好奇,你真的需要处理除了空字符串之外的任何场景吗?如果恶意进行(为了触发警告),它可能只是其他东西,但由于你在生产中禁用display_errors
,没有人可以从中获取任何信息。