深度解剖session運行原理

已經大半年沒有更新博客了,一方面有比博客更重要的事情要作,另一方面也沒有時間來整理知識,因此但願在接下來的日子裏面可以多多的寫博客來與你們交流php

什麼是session

 session的官方定義是:Session:在計算機中,尤爲是在網絡應用中,稱爲「會話控制」。Session 對象存儲特定用戶會話所需的屬性及配置信息。
redis

 說白了session就是一種能夠維持服務器端的數據存儲技術。session主要有如下的這些特色:mongodb

 

 1. session保存的位置是在服務器端數據庫

 2. session通常來講是要配合cookie使用,若是是瀏覽器禁用了cookie功能,也就只可以使用URL重寫來實現session存儲的功能後端

 3. 單純的使用session來維持用戶狀態的話,那麼當同時登陸的用戶數量較多的時候,或者存在較多的數量的session會致使查詢慢的問題瀏覽器

 本質上:session技術就是一種基於後端有別於數據庫的臨時存儲數據的技術安全

 

爲何要有session

 主要的一個緣由就是HTTP的無狀態性bash

 由於HTTP的無狀態性,因此咱們沒有辦法在HTTP發送請求的時候知道當前用戶的狀態,也就是好比說,當前是哪一個用戶的之類的這種信息,因此這個時候咱們須要session來標識當前的狀態服務器

 

seesion的工做原理

  接下來,經過一個模擬用戶登陸的流程圖來初步理解session的原理,假設這個時候用戶執行登陸操做,具體的session工做流程以下:cookie

 

整個流程大概分紅這樣的幾步:

1. 第一步將本地的cookie中的session標識和用戶名,密碼帶到後臺中

2. 第二步後臺檢測有沒有對應的session標識,咱們以php爲例,那麼就是檢測有沒有接收到對應的PHPSESSID

3. 沒有的話直接生成一個新的session。有的話,檢測對應的文件是否存在而且有效

3. 失效的話,咱們須要清除session而後生成新的session。不失效,使用當前的session

看到這裏你可能對session的工做原理有一個初步的理解

session的原理圖以下:

 

session的常見配置

 咱們這裏以PHP爲例來說解一下關於session的配置

 首先咱們要在PHP的安裝目錄下面找到php.ini文件,這個文件主要的做用是對PHP進行一些配置,具體之後涉及到再詳講。

  1. 設置session存放在cookie中中標識的字段名,php中默認爲PHPSESSID

  對應的設置爲:session.name = PHPSESSID

  2. 若是客戶端禁用了cookie,能夠經過設置session.use_trans_sid來使標識的交互方式從cookie變爲url傳遞

    對應的設置爲: session.use_trans_sid = 0

  3. 設置session的保存位置

  對應的設置是session.save_path="D:\phpStudy\PHPTutorial\tmp\tmp"

 

PHP中session實戰

 首先咱們須要安裝wamp或者是phpstudy,具體方式自行百度

 爲了方便觀察session文件的變化,咱們須要找到session的保存路徑(在php.ini中找到session.save_path),以下:

 

 而後找到所指向的目錄,注意通常來講session是使用files的形式來保存的,可是咱們也能夠根據本身的實際狀況進行修改。咱們能夠在php.ini文件中進行修改和查看。

 

 使用session的第一步,咱們要打開session,使用session_start(),而後咱們給建立的session添加一個變量,咱們假設爲demo1,值爲default ,代碼以下:

<?php
/**
 * Created by PhpStorm.
 * Date: 2017/12/16
 */
session_start();// 打開session
$_SESSION["demo1"] = "default";
?>

 

執行效果以下:

 打開對應的文件,裏面的內容以下:

 s:7 表示的是類型爲string類型,長度爲7個長度的字符串

 若是咱們對session中的內容進行從新編輯的話,效果以下:

 咱們觀察最近一條的修改日期,咱們能夠發現就是日期發生了變化,可是文件名沒有變化,也就是說,修改session中的內容不會致使文件被新建,而是執行對文件的從新寫入操做

 session的銷燬

 銷燬session通常有兩種方式,unset和session_destroy,咱們先來講說第一種

 代碼以下:

<?php
/**
 * Created by PhpStorm.
 * Date: 2017/12/16
 */
session_start();// 打開session
$_SESSION["demo1"] = "default_1";
//session的銷燬
unset($_SESSION);
?>

 

這一個至關於沒有刪除session文件,可是使得即便有對應的PHPSESSID也沒法獲取到相應的session

session_destroy()相對來講比較完全,直接刪除對應的session文件

 

<?php
/**
 * Created by PhpStorm.
 * Date: 2017/12/16
 */
session_start();// 打開session
$_SESSION["demo1"] = "default_1";
var_dump(session_name());
//session的銷燬
session_destroy();
?>

 

 

 

運行的效果以下:

對於我的來講比較推薦使用第二種方法,由於當要銷燬session的時候,那麼也就意味着session已經失效了,因此這個時候咱們把它給刪掉纔是最好的處理方式,一方面能夠減小對硬盤的存儲,另一方面能夠相對優化session的查詢速度。

 好了,這個時候咱們應該要設置傳遞給瀏覽器端的cookie了,默認是自動傳送,可是咱們應該要學習的是怎樣經過後端設置cookie過去

其中有兩個方法與session有關的方法咱們須要記住,第一個是session_name(),這個是獲取cookie的key值得,第二個是session_id,這個是session的文件名

設置的示例代碼:

<?php
/**
 * Created by PhpStorm.
 * Date: 2017/12/16
 */
session_start();// 打開session
$_SESSION["demo1"] = "default_1";
setCookie(session_name(),session_id(),time()-1000);
?>

 

在設置cookie的時候,咱們爲了程序的安全性,咱們應該要禁止JS能夠對cookie進行重寫,因此須要設置HTTP ONLY,具體的設置方法在Php.ini中找到session.cookie_httponly

而後將其的值設置爲1或者true便可

除此以外還能夠經過setCookie和ini_set()來動態設置HTTPONLY屬性

在使用session的時候,雖然會從瀏覽器把PHPSESSID傳給後端,可是這個課程不須要人爲的去參與。咱們只須要保證HTTPONLY被設置就好了。下面是完整的代碼:

 

<?php
/**
 * Created by PhpStorm.
 * Date: 2017/12/16
 */
session_start();// 打開session
if ($_SESSION) {
    var_dump($_SESSION["demo1"]);
} else {
    $_SESSION["demo1"] = "default_" . time();
    var_dump($_SESSION["demo1"]);
    setCookie(session_name(), session_id(), time(), NULL, NULL, NULL, true);
}

?>

 

 

 

 

session的一些相關注意事項

 1. 關閉瀏覽器session一樣存在

 若是咱們沒有人爲的去設置cookie的生命週期的時候默認關閉瀏覽器session的狀態是沒法被保存下來的,由於沒有設置cookie的生命週期,默認這個時候cookie爲session cookie也就是在會話存在的時候cookie纔有效,因此關閉瀏覽器cookie失效,致使後端拿不到對應的PHPSESSID,因此沒法找到對應的session文件

2.  session性能瓶頸怎樣解決?

若是是後端存在大量的session的時候,那麼這個時候就會出現性能的瓶頸,例如:當後端同時存在有5000個session文件的時候,假設要找的文件是在第4999個,那麼也就是說前面至少須要遍歷4998次,這樣就會浪費過多的時間在後端的循環遍歷查找文件中,因此這個時候最有效的方法是使用redis或者mongodb,原理是經過將本來保存在本地的session文件寫入到內存中,經過內存換空間的形式來達到提高速度

3. 通常不使用URL重寫的方法來傳遞PHPSESSID

其中主要有兩個緣由,一個是URL重寫方式傳遞的話會致使URL混亂,影響美觀。另外一個是增大了用戶誤操做的概率

更多的session的相關配置請點擊這裏

  

更多的一些PHP.ini中session的含義
[Session]
session.save_handler = files  #session的存儲方式
session.use_cookies= 1  #使用cookies在客戶端保存會話
session.use_only_cookies = 1  #去保護URL中傳送session id的用戶
session.name = PHPSESSID  #session名稱(默認PHPSESSID)
session.auto_start = 0  #不啓用請求自動初始化session
session.cookie_lifetime = 0  #cookie存活時間(0爲直至瀏覽器重啓,單位秒)
session.cookie_path = /  #cookie的有效路徑
session.cookie_domain =  #cookie的有效域名
session.cookie_httponly =  #httponly標記增長到cookie上(腳本語言沒法抓取)
session.serialize_handler = php  #PHP標準序列化
 
session.gc_probability =1
session.gc_divisor =1000  #建議設置1000-5000
#機率=session.gc_probability/session.gc_divisor(1/1000)
#頁面訪問越頻繁機率越小
session.gc_maxlifetime =1440  #過時時間(默認24分鐘,單位秒)
 
session.bug_compat_42 = off  #全局初始化session變量
session.bug_compat_warn = off
session.referer_check =  #防止帶有ID的外部URL
session.entopy_length = 0  #讀取的字節
session.cache_limiter = {nocache,private,pblic}  #HTTP緩衝類型
session.cache_expire = 180  #文檔過時時間(分鐘)
session.use_trans_sid = 1  #trans_sid支持(默認0)
session.hash_function = 0  #hash方法{0:md5(128 bits),1:SHA-1(160 bits)}
session.hash_bits_per_character = 5  #當轉換二進制hash數據奧可讀形式是,每一個字符保留位數
session.save_path =  "/var/lib/php/session"  #session id存放路徑
相關文章
相關標籤/搜索