zoukankan      html  css  js  c++  java
  • discuz清空session,导致session保存机制失败,session无法更新与解决

    
    
    <?php
    
    function userErrorHandler() {
        $e = func_get_args();
        echo '<pre style="color:red;"><br/>----------运行出错---------:<br/>'.print_r($e, 1).'<br/>----------运行出错---------<br/></pre>';
    }
    set_error_handler("userErrorHandler");
    set_exception_handler("userErrorHandler");
    
    function shutdown() {
        $a=error_get_last();    
        if($a != null) echo '<pre style="color:red;"><br/>++++++低级错误+++++<br/>'.print_r($a, 1).'<br/>++++++低级错误+++++<br/></pre>';   
    } 
    
    register_shutdown_function('shutdown');//如果使用了exit将不运行此脚本
    
    
    switch($_GET['how']) {
    	case 's'://set
    		session_start();
    		$_SESSION['qidizi'] = rand();
    		echo $_SESSION['qidizi'];
    		break;
    	case 'u'://unset
    		session_start();
    		$_SESSION['qidizi'] = 'qidiziUNSET';
    		echo $_SESSION['qidizi'];
    		break;
    	case 'g'://get
    		session_start();
    		var_dump($_SESSION);
    		break;
    	case 'c'://clean
    		session_start();
    		echo 'get---------<br/>';
    		var_dump($_SESSION);
    		echo '<br/>edit-------</br/>';
    		$_SESSION['qidizi'] = 'qidiziCLEAN';
    		var_dump($_SESSION);
    		echo '<br/>under clean---------<br/>';
    		$GLOBALS['_SESSION']=null;unset($GLOBALS['_SESSION']);//unset后,session会失效
    		empty($GLOBALS['_SESSION']) && ($GLOBALS['_SESSION']['qidiziReBuid'] = '1');//本句并不能重建/重触发session保存机制
    			session_write_close();//提前保存session改变,discuz清除了session导致保存机制失败,by qidizi,这句话才有效,提交保存
    		var_dump($_SESSION);
    		break;
    }


    以上是测试代码


    关键是在 $GLOBALS['_SESSION']=null; 这句.且

    unset($GLOBALS['_SESSION']);

    会让session在解析结束保存session的机制失败,看起来是这样的.不懂session自动保存的机制是怎么样的.演示代码中简单的重建并没有触发保存机制.

    所以,后来我使用了提前调用方法提前保存我的session更改.

    在discuz_application这个类中有对全局变量进行清空,

    因为
    正面面变量不需要保留,


        var $superglobal = array(
            'GLOBALS' => 1,
            '_GET' => 1,
            '_POST' => 1,
            '_REQUEST' => 1,
            '_COOKIE' => 1,
            '_SERVER' => 1,
            '_ENV' => 1,
            '_FILES' => 1,
        );

    接着正面的代码就会对它进行清空



            foreach ($GLOBALS as $key => $value) {
                if (!isset($this->superglobal[$key])) {
                    $GLOBALS[$key] = null; unset($GLOBALS[$key]);
                }
            }

    最终效果出现如下的代码功能
    关键是在 $GLOBALS['_SESSION']=null; 这句.

    使用我上面的测试代码进行演示:
    正面的说法指 local.q/t.php?how=s(设置)|g(获取)|u(修改)|c(清空)

    操作步骤1 设置 -> 获取 -> 修改 -> 获取     ==== 结果,修改能反馈到获取时的结果中
    操作步骤2 设置->获取 -> 修改-> 获取 -> 清空 -> 获取 ====结果:获取修改后数据正常.获取清空的数据失败,获取到的是修改时的数据.(注意这里的测试并没有把提前)



    问题就是disucz的init方法导致清空相同的效果.导致某些情况下的使用session会出现清除不掉的问题.简单就是导致验证码输入一次就可以无限提交.

    虽然可以使用其它方法来防止.但是这个session的正常的机制被破坏了.问题比较多.

    目前我在写这个时,还不清楚使用什么方法可以恢复它的机制.上面的尝试方法并不起作用.




    经过测试发现使用 session_write_close();提前保存session理性.即可解决我遇到的问题,不知为何经过清空session后,自动保存会失效.需要主动保存.

  • 相关阅读:
    H
    饭卡(0 1背包)
    J
    H
    E
    3991: [SDOI2015]寻宝游戏
    CF 1051 F. The Shortest Statement
    CF 643 E. Bear and Destroying Subtrees
    4567: [Scoi2016]背单词
    4946: [Noi2017]蔬菜
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3143249.html
Copyright © 2011-2022 走看看