標籤

ASP.NET MVC (29) Visual C# (15) JQuery (10) Plugins (8) JQuery Plugins (6) JavaScript (6) MySQL (5) CSS (4) LinQ (4) Mac OS (4) CentOS (3) Design Pattern (3) Entity Framework (3) IIS (3) Python (3) Windows (3) php (3) Docker (2) LAMP (2) SQL Server (2) WCF (2) .NET (1) .NET Core (1) AWS (1) Browser (1) GIS (1) IE (1) Internet Security (1) Linux (1) Platform (1) React (1) SEO (1) Testing (1) VMware (1) Windows 7 (1) cookie (1) curl (1) laravel (1) phpBB (1) session (1) 中古屋 (1) 透天 (1) 閒言閒語 (1) 面試 (1) 鳥松 (1)

2016年9月13日 星期二

[PHP] PHP的Session外部儲存機制探討

PHP中存取Session可直接對$_SESSION變數做操作,

預設Session會儲存在伺服器中的檔案下, 可以由php.ini中的session.save_path去設定.

在只有單一台Web Server沒有什麼問題, 如果遇到多台Web Server作負載平衡的狀況,

就需要將Session放到外部單一儲存體, 例如MySQL, Redis, Memcached等.


如果PHP是新專案就較好解決, 不少現成的class(Session物件)可以使用,

若是維護PHP舊專案, 且代碼均直接使用$_SESSION變數時,

我們就只能從session.save_handler去下手.

github上也有不少透過save_handler的操作去解決Session儲存體方案, 例如:

1. MySQL

2. Redis

3. MongoDB

其實就是透過註冊以下六個事件(open; close; ...)來指定Session操作時的對應動作

session_set_save_handler('open','close', 'read','write', 'destroy','gc')

分別為開啟; 關閉; 讀取; 寫入; 消滅; 垃圾回收 六種方法.




在套用之前先了解Session的外部儲存讀取及寫入機制是如何運作的,

首先先定義六種事件, 基本上就是單純的echo輸出:



測試Session讀取:

Session讀取結果:



測試Session寫入:
Session寫入結果:



從結果發現, 無論是單獨讀取還是單獨寫入, Session都會呼叫read, write 兩個操作事件,

所以在介接外部儲存體時需要注意讀寫效能問題.

另外註冊的destroy()事件在呼叫session_destroy()方法時就會觸發執行.

而註冊的gc()事件則是由php.ini設定機率(例如1%)去觸發執行.






以上完整範例原始碼放在github

Reference:
http://php.net/manual/en/class.sessionhandler.php