完全明白php的session機制

1.session.save_handler = files

    * 1 . session_start ()
        
1) . session_start ()是session機制的開始,它有必定機率開啓垃圾回收 , 由於session是存放在文件中,
PHP自身的垃圾回收是無效的,SESSION的回收是要刪文件的,這個機率是根據php
. ini的配置決定的,
可是有的系統是 session
. gc_probability = 0 ,這也就是說機率是0,而是經過cron腳原本實現垃圾回收。

            session
. gc_probability = 1
            session
. gc_divisor = 1000
            session
. gc_maxlifetime = 1440 // 過時時間 默認24分鐘
            //機率是 session.gc_probability/session.gc_divisor 結果 1/1000,
            //不建議設置太小,由於session的垃圾回收,是須要檢查每一個文件是否過時的。

            session . save_path = // 好像不一樣的系統默認不同,有一種設置是 "N;/path"
            //這是隨機分級存儲,這個樣的話,垃圾回收將不起做用,須要本身寫腳本


        
2 ). session會判斷當前是否有 $_COOKIE [ session_name ()]; session_name ()返回保存session_id的COOKIE鍵值,
這個值能夠從php
. ini找到

            session
. name = PHPSESSID // 默認值PHPSESSID
            

        
3) . 若是不存在會生成一個session_id , 而後把生成的session_id做爲COOKIE的值傳遞到客戶端 .
至關於執行了下面COOKIE 操做,注意的是,這一步執行了setcookie()操做,COOKIE是在header頭中發送的,
這以前是不能有輸出的,PHP有另一個函數
session_regenerate_id () 若是使用這個函數,這以前也是不能有輸出的。

               
setcookie ( session_name () ,
                         
session_id () ,
                          session
. cookie_lifetime , // 默認0
                          session . cookie_path , // 默認'/'當前程序跟目錄下都有效
                          session . cookie_domain , // 默認爲空
                          )

        
4 ). 若是存在那麼session_id = $_COOKIE [ session_name ];
            而後去session
. save_path指定的文件夾裏去找名字爲 ' SESS_ ' . session_id ()的文件 .
            讀取文件的內容反序列化,而後放到
$_SESSION中
   
* 2 . $_SESSION賦值
      好比新添加一個值
$_SESSION [ ' test ' ] = ' blah ' ; 那麼這個 $_SESSION只會維護在內存中 ,當腳本執行結束的時候,
用把
$_SESSION的值寫入到session_id指定的文件夾中 ,而後關閉相關資源 .       這個階段有可能執行更改session_id的操做,
好比銷燬一箇舊的的session_id,生成一個全新的session_id
. 一半用在自定義 session操做,角色的轉換上,
好比Drupal
. Drupal的匿名用戶有一個SESSION的,當它登陸後須要換用新的session_id

       
if ( isset ( $_COOKIE [ session_name ()])) {
         
setcookie ( session_name () , '' , time () - 42000 , ' / ' ); // 舊session cookie過時
        }
       
session_regenerate_id (); // 這一步會生成新的session_id
       //session_id()返回的是新的值


     
3 . 寫入SESSION操做
      在腳本結束的時候會執行SESSION寫入操做,把
$_SESSION中值寫入到session_id命名的文件中 ,可能已經存在,
可能須要建立新的文件。
   
* 4 . 銷燬SESSION
      SESSION發出去的COOKIE通常屬於即時COOKIE,保存在內存中,當瀏覽器關閉後,纔會過時,假如須要人爲強制過時,
好比 退出登陸,而不是關閉瀏覽器,那麼就須要在代碼裏銷燬SESSION,方法有不少,
          o
1 . setcookie ( session_name () , session_id () , time () - 8000000 , .. ); // 退出登陸前執行
          o 2 . usset( $_SESSION ); // 這會刪除全部的$_SESSION數據,刷新後,有COOKIE傳過來,可是沒有數據。
          o 3 . session_destroy (); // 這個做用更完全,刪除$_SESSION 刪除session文件,和session_id

      當不關閉瀏覽器的狀況下,再次刷新,2和3都會有COOKIE傳過來,可是找不到數據

2.session.save_handler = user


      用戶自定義session處理機制,更加直觀
   
* session_set_save_handler ( ' open ' , ' close ' , ' read ' , ' write ' , ' destroy ' , ' gc ' );
1 . session_start () ,
      執行open(
$save_path , $session_name )打開session操做句柄
     
$save_path 在session . save_handler = files的狀況下它就是session . save_path,
可是若是用戶自定的話,這個兩個參數都用不上,直接返回TRUE

      執行read(
$id )從中讀取數據 . // 這個參數是自動傳遞的就是session_id(),能夠經過這個值進行操做。
    * 2 . 腳本執行結束
      執行write(
$id , $sess_data ) // 兩個參數,很簡單
    * 3 . 假如用戶須要session_destroy()

      先執行destroy.在執行第2步 php

//SESSION初始化的時候調用
      function open($save_path, $session_name)
      {
        global $sess_save_path;
        $sess_save_path = $save_path;
        return(true);
      }

      //關閉的時候調用
      function close()
      {
        return(true);
      }

      function read($id)
      {
        global $sess_save_path;
        $sess_file = "$sess_save_path/sess_$id";
        return (string) @file_get_contents($sess_file);
      }
      //腳本執行結束以前,執行寫入操做
      function write($id, $sess_data)
      {
        echo "sdfsf";
        global $sess_save_path;

        $sess_file = "$sess_save_path/sess_$id";
        if ($fp = @fopen($sess_file, "w")) {
          $return = fwrite($fp, $sess_data);
          fclose($fp);
          return $return;
        } else {
          return(false);
        }

      }

      function destroy($id)
      {
        global $sess_save_path;

        $sess_file = "$sess_save_path/sess_$id";
        return(@unlink($sess_file));
      }

      function gc($maxlifetime)
      {
        global $sess_save_path;

        foreach (glob("$sess_save_path/sess_*") as $filename) {
          if (filemtime($filename) + $maxlifetime < time()) {
            @unlink($filename);
          }
        }
        return true;
      }


session與cookie區別:
web

       爲何會有cookie呢,你們都知道,http是無狀態的協議,客戶每次讀取web頁面時,服務器都打開新的會話,並且服務器也不會自動維護客戶的上下文信息,那麼要怎麼才能實現網上商店中的購物車呢? 瀏覽器

        session就是一種保存上下文信息的機制,它是針對每個用戶的,變量的值保存在服務器端,經過SessionID來區分不一樣的客戶,session是以cookie或URL重寫爲基礎的,默認使用cookie來實現,系統會創造一個名爲 JSESSIONID的輸出cookie,咱們叫作session cookie; 以區別persistent cookies,也就是咱們一般所說的cookie,注意session cookie是存儲於瀏覽器內存中的,並非寫到硬盤上的,這也就是咱們剛纔看到的JSESSIONID,咱們一般情是看不到JSESSIONID的。 安全

        可是當咱們把瀏覽器的cookie禁止後,web服務器會採用URL重寫的方式傳遞Sessionid,咱們就能夠在地址欄看到 sessionid=KWJHUG6JJM65HS2K6之類的字符串。 服務器

         明白了原理,咱們就能夠很容易的分辨出persistent cookies和session cookie的區別了,網上那些關於二者安全性的討論也就一目瞭然了,session cookie針對某一次會話而言,會話結束session cookie也就隨着消失了,而persistent cookie只是存在於客戶端硬盤上的一段文本(一般是加密的),並且可能會遭到cookie欺騙以及針對cookie的跨站腳本攻擊,天然不如 session cookie安全了。 cookie

         一般session cookie是不能跨窗口使用的,當你新開了一個瀏覽器窗口進入相同頁面時,系統會賦予你一個新的sessionid,這樣咱們信息共享的目的就達不到 了,此時咱們能夠先把sessionid保存在persistent cookie中,而後在新窗口中讀出來,就能夠獲得上一個窗口SessionID了,這樣經過session cookie和persistent cookie的結合咱們就實現了跨窗口的session tracking(會話跟蹤)。 session

         在一些web開發的書中,每每只是簡單的把Session和cookie做爲兩種並列的http傳送信息的方式,session cookies位於服務器端,persistent cookie位於客戶端,但是session又是以cookie爲基礎的,明白的二者之間的聯繫和區別,咱們就不難選擇合適的技術來開發web service了。
dom

相關文章
相關標籤/搜索