在PHP中销毁会话时出错

在PHP中销毁会话时出错,php,session,Php,Session,我在PHP(版本5.2.10)的会话处理中遇到问题。我正在使用下面提到的功能进行登录、注销和验证会话 login() { session_set_cookie_params(0); session_start(); session_regenerate_id(true); $_SESSION['user_id'] } validate_session() { session_set_cookie_params(0); session_start(

我在PHP(版本5.2.10)的会话处理中遇到问题。我正在使用下面提到的功能进行登录、注销和验证会话

login() { session_set_cookie_params(0); session_start(); session_regenerate_id(true); $_SESSION['user_id'] } validate_session() { session_set_cookie_params(0); session_start(); if (isset($_SESSION['user_id']) === FALSE) { session_destroy(); logout(); header("Location: login_page"); } } logout() { session_set_cookie_params(0); session_start(); $_SESSION = array(); setcookie(session_name(), '', time() - 3600, '/'); session_destroy(); } 登录() { 会话设置cookie参数(0); 会话_start(); 会话\u重新生成\u id(true); $\会话['user\u id'] } 验证会话() { 会话设置cookie参数(0); 会话_start(); 如果(isset($\u会话['user\u id'])==FALSE){ 会话_destroy(); 注销(); 标题(“位置:登录页面”); } } 注销() { 会话设置cookie参数(0); 会话_start(); $\会话=数组(); setcookie(session_name(),'',time()-3600'/'); 会话_destroy(); } 每个页面首先调用validate_session()函数。如果会话无效,它将重定向到登录页面。login()函数用于为用户创建会话。 当用户单击logout时,将调用logout()函数来销毁会话

问题是:logout()函数随机抛出警告:
警告:会话_销毁():会话对象销毁失败

我很少收到这样的警告。在20-30个注销电话中,我只收到一次。有什么想法吗

我正在windows xp机器上开发

更新:会话存储在文件系统中。

路径:C:\WINDOWS\Temp

您如何存储会话?如果是基于文件的,可能是超时或权限错误

另外,我想知道REGENATE_id是否导致销毁函数查找技术上不再存在的会话。您是否尝试过在REGENATE函数中将该布尔参数设置为false

我们在CakePHP应用程序中遇到了这个问题,但我们通过调整蛋糕设置来纠正它。

找到了在这个主题上可能有用的方法。基本问题是:

  • 会话开始时是否有效--
    session\u start()
    的返回值是多少
  • 会话文件是否存在于PHP.ini
    session.save_path中,并且可以删除
  • 我怀疑你是第一个。我不记得在哪里,但我想我看到过这样的情况:会话本身失效,然后出于某种原因尝试重复该过程。

    是否在validate_session()之外的其他地方调用logout()?如果不是,问题可能是在注销()之前调用会话_destroy()

    你可以试试这个:

    validate_session()
    {
        session_set_cookie_params(0);
        session_start();
        if ( !isset( $_SESSION['user_id'] ) ) {
            logout();
            header("Location: login_page");
        }
    }
    
    logout()
    {
        $_SESSION = array();
        setcookie(session_name(), '', time() - 3600, '/');
        session_destroy();
    }
    

    看来你已经很久没有接受任何关于stackoverflow的答案了…是的!我在stackoverflow中不是很活跃。在某些情况下,我还没有得到令人满意的答案。嗨,瓦伦,你能解释一下为什么在比较中使用trip equals吗?通常情况下,如果(!isset())足够了,我知道它更可靠,但是isset()应该只返回布尔值,您真的需要验证它的类型吗?可能不太可能,但可能偶尔会在不应该的情况下返回true?建议将
    debug\u print\u backtrace()
    添加到注销函数,并跟踪输出,然后比较输出,如果存在差异,则可能是不同的调用路径导致了错误。(请参阅)感谢大家的建议。我无法复制此内容(我使用的代码与前面相同)。事实上,我很久没有看到这个错误了。现在我不知道是什么导致了这个。会话存储在文件系统中。我也尝试了你的建议,但还是有一次出错。正如我提到的,错误很少发生(有时一天发生一次),我很难做出一些更改,然后看看它是否解决了问题。另一个问题是,当警告出现时,用户是否真的注销了?或者更重要的是,除了警告之外,其他一切都正常吗?如果是这样的话,你可能会考虑到警告,直到它被计算出来,也就是说,如果这是一个生产环境。这也是我的首选解决方案,将SouthSyDebug添加到注销函数而不是ValueTyScript()函数是合乎逻辑的。此解决方案提供的一个优点是防止在注销页面上创建新会话,这将消除复制会话_destroy()函数的需要。