PHP session的使用

FreeeLinux發表於2017-03-29

對比cookie

cookie的缺點:

  • 會話資料原文儲存於瀏覽器端,原始資料的安全性較低。
  • 如果cookie資料量較大,由於每次請求都要攜帶,會增加頻寬的使用。

如何解決這兩個問題呢?
使用session技術來實現。將會話資料儲存於伺服器端。同時使會話資料可以區分瀏覽器。
為每個會話資料建立獨立的會話資料區(來儲存當前會話的全部資料),每個會話資料區都存在唯一的標誌,同時瀏覽器端儲存該唯一標誌(攜帶的少!),做配對使用!

相對cookie安全一些,但是也可以偽造(直接使用別人的session id)。

開啟session機制

函式:session_start();
也可以通過php.ini設定為自動開啟,設定session.auto_start();

利用$_SESSION操作session資料

增,刪,改,查,都是使用$_SESSION完成,每個元素就是一個session資料,元素的鍵就是session資料的名,元素的值就是資料。

每一個指令碼週期之內想讀session必須先開啟!

session原理

儲存於瀏覽器端cookie中的session-id,就是一個普通的cookie變數,不過具有特殊的意義。
每個會話,所生成儲存於伺服器端的session資料區。預設的,以檔案的形式,儲存於伺服器端作業系統的臨時目錄中。

session資料屬性

  • 有效期:會話週期
  • 有效路徑:預設有效路徑整站有效。和cookie不一樣,不僅子目錄可以保持session,回到父目錄session同樣存在。
  • 有效域:預設僅在當前域有效
  • 是否僅安全連線傳輸:否
  • 是否httponly:

以上session資料的特徵,都是由,瀏覽器cookie中所儲存的session-id cookie變數所導致的。
可見,如果需要更改session資料的屬性,則需要更改儲存session-id的cookie變數PHPSESSIONID的屬性。

  1. php.ini中存在該屬性的配置。此種方法會影響其他指令碼。
  2. 通過在指令碼中, 使用函式int_set()來進行配置的修改,僅在設定後的指令碼週期內有效,要保證在開啟session前設定完畢。ini_set(‘選項’, ‘值’);
  3. 使用特定的功能函式,session_set_cookie_params(有效期,有效路徑,有效域,是否僅安全傳輸,是否httponly)完成設定。注意必須在session_start()之前設定,有效期是一個時間間隔

選項的設定是針對cookie中的session-id的,所有的session資料有效。

session的資料通常保持預設值,不建議修改!如果某個資料需要長時間儲存,建議用cookie,因為cookie儲存在瀏覽器端,不會對伺服器造成壓力。

語法

cookie資料必須是字串型別,session可以使任何型別。因為session的資料時序列化儲存的。不過不包含資源型別!

session_start()之前不能有輸出!

session資料區

在指令碼週期結束後,持久儲存當前會話session資料的區域。
在指令碼週期內,使用$_SESSION這個變數管理的會話session資料。

銷燬

session_destroy()函式。
銷燬:刪除當前的資料區,關閉session機制。在銷燬session後,由於$_SESSION變數在記憶體中,所以還可以用,只是不會結束時不會寫入到資料區了。因此,下次指令碼週期不能獲取儲存的session資料了。

面試題1:如何完整刪除與當前session相關的全部資料?
(分析:刪除資料區,刪除$_SESSION變數)。

  1. session_destroy(); 刪除資料區
  2. unset($_SESSION); 銷燬變數
  3. setCookie(session_name(), ”, time()-1),銷燬cookie中的session-id

tip:PHPSESSID,稱之為session.name可以被配置的php.ini,使用函式session_name()來獲取當前的值。

面試題2:如何清空session資料?
不要unset(SESSION)

重寫session的儲存機制:
目的:

  1. 便於管理大量的session資料
  2. 便於web伺服器叢集鍾祥session資料

方案:入庫,入記憶體

實現過程:
定義(實現)自定義的相關儲存處理函式。將其設定為session機制需要的儲存函式(告知session機制,使用我們的函式完成儲存處理)

session機制,共需要6個儲存處理函式。使用php函式,session_set_save_handler(開始處理器,結束處理器,讀處理器,寫處理器,刪除處理器,垃圾回收處理器)。

使用資料庫儲存

讀操作

直接從資料區讀即可。

寫操作

寫操作不需要每次都執行,如果已經插入過了,只需要替換即可。

insert into ... ON DUPLICATE KEY UPDATE
REPLACE 語法與isnert一致,存在則替換,不存在則插入

刪除操作

在開啟session機制的過程中,有概率的執行垃圾回收操作。預設的概率為1/1000。可以配置:

session.gc_probability = 1
session.gc_divisor = 1000

垃圾回收操作

PHP session機制設定session資料區的最大有效期,某條session記錄(資料區),在最後一次處理後,如果超過了多久之後沒有被使用,則被視為垃圾資料。
該時間預設1440s,可以被配置(php.ini中)。

同時需要記錄每個session資料區的最後處理時間。與當前時間比較,如果之差大於1440,則說明已經過期。

所以,我們在資料庫中需要增加欄位,來儲存最後處理時間。

垃圾回收是被基本上是別的瀏覽器觸發的!因為先讀後垃圾回收再寫,回收了一次但又寫了一次,相當於沒有垃圾回收,並且還把時間戳更新了

開始

session開啟時,最早執行的一個儲存機制的相關方法,用於初始化儲存操作的相關資源。比如,連線資料庫。

結束

在session機制關閉時,執行的方法,最後一個執行的儲存相關操作,用於收尾性工作。

補充

先執行session_set_save_handler(),再執行session_start()。
保證session不自動開啟,在php.ini中讓session_auto_start=0。Appache可以通過.htaccess檔案配置,php_flag session.auto_start 0(我沒用Apache:))。

配置php.ini中session.save_handler預設為files。建議:重寫session儲存機制後, 應該將其改為user表示使用者自定義!
程式碼中呼叫玩session_set_save_handler()函式之後呼叫:

ini_set('session.save_handler', 'user');

cookie和session的差異

聯絡:

  • 都是實現會話的方案。
  • session基於cookie。

差異:

cookie session
會話儲存位置 瀏覽器端
安全性
資料傳輸量
支援會話資料量 參考限制:4k,20個
支援的資料型別 字串

session資料的持久化問題

修改兩點:
瀏覽器端的session-id:session_set_cookie_params(時間);
伺服器端session資料區:ini_set(‘session.gc_maxlifetime’, ‘時間’);

session很少做持久化,所以如果需要持久儲存就去選擇cookie。

cookie僅用,session是否可用?

常規;cookie禁用,session不能使用。
技術上,可以使用:cookie用來儲存session的id,每次請求時攜帶。通過GET或POST的方式向伺服器傳遞session-id。

PHP提供的配置:

session.use_only_cookies = 1
session.use_trans_sid = 0

同樣可以用ini_set函式修改。

相關文章