有些情况下session_start();
即使无法实际启动会话也会返回true。从错误日志中可以看出:
PHP Warning: session_start():
open(/var/lib/php5/sessions/sess_XXXXXXX, O_RDWR) failed:
Permission denied (13)
如果程序员认为他可以在不同的网站上使用相同的会话ID,但他们实际上使用不同的权限并且无法访问其他文件,我发现这种情况会发生。我不能说这个程序员,比如,嘿,检查一下session_start()
返回并采取相应的行动,因为他告诉我他检查并报告所有好处。
可以通过从特定会话文件中删除写权限来模拟此问题:
chmod a-w /var/lib/php5/sessions/sess_XXXXXXX
然后用相同的ID盯着会话:
session_start(); // returns true with a warning in the logs
// if it'd return false, there would be no question
// PHP thinks session is started: session_status() == PHP_SESSION_ACTIVE
在软件中处理此类错误的正确方法是什么?例如。我怎么知道我有这种错误而不是查看日志?
到目前为止,我已经达到了这个目标:
set_error_handler(function ($errno, $errstr) {
// we got an error during session_start()
if (strpos($errstr, 'session_start') === 0) {
// forget previus session ID
session_regenerate_id();
// restore the handler for now
set_error_handler(null);
}
return false;
}, E_WARNING);
if (!session_start()) {
// et cetera
}
// session shall be running now
// restore the error handler
set_error_handler(null);
(我的灵感来自phpMyAdmin,also does something similar。)
答案 0 :(得分:0)
捕获错误和警告很有趣,但你永远不知道你是否正确。你真正需要的是检查你是否可以在会话中保存一些内容。
function verify_session_writable()
{
// if session has been started yet there's no canary
if (empty($_SESSION[__FUNCTION__]) &&
session_status() == PHP_SESSION_ACTIVE) {
// set the canary
$_SESSION[__FUNCTION__] = 1;
// write the session to a file
session_write_close();
// and load it once again
session_start();
// if there's no canary, it's an error
if (empty($_SESSION[__FUNCTION__])) {
// change session ID to make sure the write
// happens to a file with a different name
session_regenerate_id();
// set the canary to skip futher checks
$_SESSION[__FUNCTION__] = 1;
}
}
}
我在每个需要确保可以保存会话的地方调用此功能,例如在购物车更新期间。
答案 1 :(得分:-1)
您不应该尝试使用软件解决此问题,您应该更正服务器配置。在这种情况下,请确保服务器正在运行的用户 - 无论是apache还是www-data或nobody,都具有PHP会话存储目录和文件的写权限。
您可以使用以下命令找出运行PHP的用户:
<?php echo `whoami`; ?>