处理session_start()失败的情况返回true

时间:2015-04-27 03:14:58

标签: php session

有些情况下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。)

2 个答案:

答案 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`; ?>