深入講解PHP Session及如何保持其不到期的方法_php技巧

來源:互聯網
上載者:User

SESSION的實現中採用COOKIE技術,SESSION會在用戶端儲存一個包含session_id(SESSION編號)的COOKIE;在伺服器端儲存其他session變數,比如session_name等等。當使用者請求伺服器時也把session_id一起發送到伺服器,通過 session_id提取所儲存在伺服器端的變數,就能識別使用者是誰了。同時也不難理解為什麼SESSION有時會失效了。

當用戶端禁用COOKIE時(點擊IE中的“工具”—“Internet選項”,在彈出的對話方塊裡點擊“安全”—“自訂層級”項,將“允許每個對話COOKIE”設為禁用),session_id將無法傳遞,此時 SESSION失效。不過php5在linux/unix平台可以自動檢查cookie狀態,如果用戶端設定了禁用,則系統自動把session_id附加到url上傳遞。windows主機則無此功能。

Session常見函數及用法?
Session_start() :開始一個會話或者返回已經存在的會話。
說明:這個函數沒有參數,且傳回值均為true。如果你使用基於cookie的session(cookie-based sessions),那麼在使用Session_start()之前瀏覽器不能有任何輸出,否則會發生以下錯誤:
Warning: Cannot send session cache limiter - headers already sent (output started at /usr/local/apache/htdocs/cga/member/1.php:2)…………


你可以在php.ini裡啟動session.auto_start=1,這樣就無需每次使用session之前都要調用session_start()。但啟用該選項也有一些限制,如果確實啟用了 session.auto_start,則不能將對象放入會話中,因為類定義必須在啟動會話之前載入以在會話中重建對象。
請求結束後所有註冊的變數都會被序列化。登入但未定義的變數被標記為未定義。在之後的訪問中這些變數也未被會話模組定義,除非使用者以後定義它們。

警告: 有些類型的資料不能被序列化因此也就不能儲存在會話中。包括 resource 變數或者有循環參考的對象(即某對象將一個指向自己的引用傳遞給另一個對象)。

註冊SESSION變數 :
PHP5使用$_SESSION[‘xxx']=xxx註冊SESSION全域變數。和GET,POST,COOKIE的使用方法相似。
注意:session_register(),session_unregister ,session_is_registered在php5下不再使用,除非在php.ini裡把register_globle設為on,不過出於安全考慮,強烈建議關閉register_globle。HTTP_SESSION_VARS也不提倡使用了,官方建議用$_SESSION代替之。例如:

    Page1.php

  <?php  Session_start(); //使用SESSION前必須調用該函數。  $_SESSION[‘name']=”我是黑旋風李逵!”; //註冊一個SESSION變數  $_SESSION[‘passwd']=”mynameislikui”;  $_SESSION[‘time']=time();  echo '  通過COOKIE傳遞SESSION'; //如果用戶端支援cookie,可通過該連結傳遞session到下一頁。  echo '  . SID . '">通過URL傳遞SESSION';//用戶端不支援cookie時,使用該辦法傳遞session.  ?>

    Page2.php

  <?php  session_start();  echo $_SESSION['name']; //  echo $_SESSION['passwd']; //  echo date('Y m d H:i:s', $_SESSION['time']);  echo '  返回山一頁';  ?>

有兩種方法傳遞一個會話 ID:

  1. cookie
  2. URL 參數

會話模組支援這兩種方法。cookie 更最佳化,但由於不總是可用,也提供替代的方法。第二種方法直接將會話 ID 嵌入到 URL 中間去。

PHP 可以透明地轉換串連。除非是使用 PHP 4.2 或更新版本,需要手工在編譯 PHP 時啟用。在 Unix 下,用 --enable-trans-sid 配置選項。如果此配置選項和運行時選項 session.use_trans_sid 都被啟用(修改php.ini),相對 URI 將被自動修改為包含會話 ID。

session_id
session_id() 用於設定或取得當前session_id。php5中既可以使用session_id(),也可以通過附加在url上的SID取得當前會話的session_id和session_name。
如果session_id()有具體指定值的話,將取代當前的session_id值。使用該函數前必須啟動會話:session_start();
當我們使用session cookies時,如果指定了一個session_id()值,每次啟動session_start()都會往用戶端發送一個cookie值。不論當前session_id是否與指定值相等。
session_id()如果沒有指定值,則返回當前session_id();當前會話沒有啟動的話,則返回Null 字元串。

檢查session是否存在?
在以往的php版本中通常使用session_is_register()檢查session是否存在,如果您使用$_SESSION[‘XXX']=XXX來註冊會話變數,則session_is_register()函數不再起作用。你可以使用
isset($_SESSION[‘xxx'])來替代。

更改session_id session_regenerate_id() 更改成功則返回true,失敗則返回false。
使用該函數可以為當前session更改session_id,但不改變當前session的其他資訊。例如:

  <?php  session_start();  $old_sessionid = session_id();  session_regenerate_id();  $new_sessionid = session_id();  echo "原始 SessionID: $old_sessionid  ";  echo "新的 SessionID: $new_sessionid  ";  echo"  ";  print_r($_SESSION);  echo"";  ?>

session_name() 返回當前session的name或改變當前session的name。如果要改變當前session的name,必須在session_start() 之前調用該函數。注意:session_name不能只由數字組成,它至少包含一個字母。否則會在每時每刻都產生一個新的session id.
session改名樣本:

$previous_name = session_name("WebsiteID");echo "新的session名為: $previous_name";?>

如何刪除session?
1、unset ($_SESSION['xxx']) 刪除單個session,unset($_SESSION['xxx']) 用來unregister一個登入的session變數。其作用和session_unregister()相同。 session_unregister()在PHP5中不再使用,可將之打入冷宮。
unset($_SESSION) 此函數千萬不可使用,它會將全域變數$_SESSION銷毀,而且還沒有可行的辦法將其恢複。使用者也不再可以註冊$_SESSION變數。
2、$_SESSION=array() 刪除多個session
3、 session_destroy()結束當前的會話,並清空會話中的所有資源。。該函數不會unset(釋放)和當前session相關的全域變數 (globalvariables),也不會刪除用戶端的session cookie.PHP預設的session是基於cookie的,如果要刪除cookie的話,必須藉助setcookie()函數。
傳回值:布爾值。
功能說明:這個函數結束當前的session,此函數沒有參數,且傳回值均為true

session_unset() 如果使用了$_SESSION,則該函數不再起作用。由於PHP5必定要使用$_SESSION,所以此函數可以打入冷宮了。

下面是PHP官方關於刪除session的案例:

  <?php  // 初始化session.  session_start();  /*** 刪除所有的session變數..也可用unset($_SESSION[xxx])逐個刪除。****/  $_SESSION = array();  /***刪除sessin id.由於session預設是基於cookie的,所以使用setcookie刪除包含session id的cookie.***/  if (isset($_COOKIE[session_name()])) {  setcookie(session_name(), '', time()-42000, '/');  }// 最後徹底銷毀session.  session_destroy();  ?>

由此我們可以得出刪除Session的步驟:

  1. session_start()
  2. $_SESSION=array()/unset($_SESSION['xxx'])
  3. session_destroy()

解決PHP Session不到期以及SessionId保持不變的問題

session 回收機制:
 
PHP採用Garbage Collection process對到期session進行回收,然而並不是每次session建立時,都能夠喚起 ‘garbage collection' process ,gc是按照一定機率啟動的。這主要是出於對伺服器效能方面的考慮,每個session都觸發gc,瀏覽量大的話,伺服器吃不消,然而按照一定機率開啟gc,當流覽量大的時候,session到期機制能夠正常運行,而且伺服器效率得到節省。細節應該都是多年的經驗積累得出的。
 
三個與PHP session到期相關的參數(php.ini中):
 

  1. session.gc_probability = 1
  2. session.gc_divisor = 1000
  3. session.gc_maxlifetime = 1440

gc啟動機率 = gc_probability / gc_divisor = 0.1%
 
session到期時間 gc_maxlifetime 單位:秒
 
當web服務正式提供時,session到期機率就需要根據web服務的瀏覽量和伺服器的效能來綜合考慮session到期機率。為每個session都開啟gc,顯然是不明智的,感覺有點“碰運氣”的感覺,要是訪問量小命中幾率就小。我在本機測試過程中,幾乎都沒有被命中過,sessionid幾天都不變,哪怕機器重啟。測試過程中,這個到期機率值要設定大一點命中幾率才高點。
 
通過修改php設定檔的到期機率值,可以“碰運氣”式的設定session到期,那有沒有更好的辦法呢?
 

下面寫的這個session類可以徹底解決session不到期以及sessionid不變的問題。
 

<?php /** * 擴充Session類(簡單封裝) *  * @author slimboy * */class Session {     /**   * 初始化   */  static function _init(){     ini_set('session.auto_start', 0);     //Session::start();    }       /**   * 啟動Session   */  static function start() {     session_start();   }     /**   * 設定Session   *    * @param $name Session名稱   * @param $value 值   * @param $time 逾時時間(秒)   */  public static function set($name,$value,$time){     if(empty($time)){       $time = 1800; //預設值      }     $_SESSION[$name] = $value;     $_SESSION[$name.'_Expires'] = time() + $time;   }       /**   * 擷取Session值   *    * @param $name Session名稱   */  public static function get($name){     //檢查Session是否已到期      if(isset($_SESSION[$name.'_Expires']) && $_SESSION[$name.'_E xpires']>time()){       return $_SESSION[$name];     }else{       Session::clear($name);       return null;     }   }           /**   * 設定Session Domain   *    * @param $sessionDomain 域   * @return string   */  static function setDomain($sessionDomain = null) {     $return = ini_get('session.cookie_domain');     if(!empty($sessionDomain)) {       ini_set('session.cookie_domain', $sessionDomain);//跨 域訪問Session      }     return $return;   }           /**   * 清除某一Session值   *    * @param $name Session名稱   */  static function clear($name){     unset($_SESSION[$name]);     unset($_SESSION[$name.'_Expires']);   }           /**   * 重設銷毀Session   */  static function destroy(){     unset($_SESSION);     session_destroy();   }           /**   * 擷取或設定Session id   */  static function sessionid($id=null){     return session_id($id);   }  }?>簡單調用: <?php  //設定session   Session::set('UserId', $userid, 3600);   //讀取session  $userId = Session::get('UserId');?>

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.