程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> discuz清空session,導致session保存機制失敗,session無法更新與解決

discuz清空session,導致session保存機制失敗,session無法更新與解決

編輯:關於PHP編程

[php] 
 
 
 
<?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; 

 


<?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; 這句.且

[php]
unset($GLOBALS['_SESSION']); 

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後,自動保存會失效.需要主動保存.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved