標籤:res php.ini 網站 建立目錄 技術 禁用 ssid 方法 名稱
一 PHP SESSION原理
session 是在伺服器端保持使用者會話資料的一種方法,而 cookie 是在用戶端保持使用者資料。HTTP 協議是一種無狀態協議,伺服器響應完之後就失去了與瀏覽器的聯絡。那麼,伺服器是如何記住眾多使用者的會話資料呢?
首先要將用戶端和伺服器端建立一對一聯絡,每個用戶端都得有一個唯一標識,這樣伺服器才能識別出來。建立唯一標識的方法有兩種:cookie 或者通過 GET 方式指定。預設配置的 PHP 使用 session 的時候會建立一個名叫 "PHPSESSID" 的 cookie(可以通過 php.ini 修改 session.name 值指定),如果用戶端禁用 cookie ,也可以指定通過 GET 方式把 session id 傳到伺服器(修改 php.ini 中 session.use_trans_sid 等參數)。
查看伺服器端 /tmp 目錄(在不修改 PHP 配置的情況下)會發現很多類似 sess_0fb45ob06s3ictc5qp98frvjl6 這樣的檔案,這個其實就是 session id "0fb45ob06s3ictc5qp98frvjl6" 對應的資料。真相就在這裡,用戶端將 session id 傳遞到伺服器,伺服器根據 session id 找到對應的檔案,讀取的時候對檔案內容進行還原序列化得到 session 的值,而儲存的時候先序列化再寫入。
事實就是這樣,所以如果伺服器不支援 session 或者你想自訂 session,通過 PHP 的 uniqid 產生永不重複的 session id,然後找個地方儲存 session 的內容即可。
二 使用 SESSION 之前為什麼必須先執行 session_start()?
瞭解 session 的原理之後,所謂的 session 其實就是用戶端一個 session id 對應伺服器端一個 session file。建立 session 之前執行 session_start() 是告訴伺服器要接收一個cookie 以及準備好 session 檔案,要不然 session 內容怎麼存;讀取 session 之前執行 session_start() 是告訴伺服器,趕緊根據 session id 把 session 檔案還原序列化。
只有一個 session 函數可以在 session_start() 之前執行,session_name():讀取或指定 session 名稱(比如預設的就是 "PHPSESSID"),這個當然要在 session_start 之前執行。
三 SESSION影響系統效能
session 在大訪問量網站上確實影響系統效能,影響效能的原因之一由檔案系統設計造成,在同一個目錄下超過10000個檔案時,檔案的定位將非常耗時,PHP支援 session 目錄hash,可以通過修改 php.ini 中 session.save_path = “2;/path/to/session/dir”,那麼 session 將儲存在兩級子目錄中,每個目錄有16個子目錄[0~f],不過 PHP session 不支援建立目錄,需要事先把那麼些目錄建立好。
還有一個問題就是小檔案的效率問題,一般 session 資料都不會太大(1~2K),如果有大量這樣1~2K 的檔案在磁碟上,IO 效率肯定會很差。
其實還有很多中儲存 session 的方式,可以通過 php -i|grep "Registered save handlers" 查看,比如 Registered save handlers => files user sqlite eaccelerator 可以通過檔案、使用者、sqlite、eaccelerator來存,如果伺服器裝了 memcached,還有 mmcache 的選項。當然還有很多,比如 MySQL、PostgreSQL 等等,都是不錯的選擇。
四 SESSION的同步
前端可能有很多台伺服器,使用者在A伺服器上登入了,種下了 session 資訊,然後訪問網站的某些頁面可能會跳到 B 伺服器上去了,如果這個時候 B 伺服器上沒有 session 資訊又沒有做特殊處理,可能就會出問題了。
session 同步有很多種,如果你是儲存在 memcached 或者 MySQL 中,那就很容易了,指定到同樣的位置即可,如果是檔案形式的,你可以用 NFS 統一儲存。
還有一種方式是通過加密的 cookie 來實現,使用者在A伺服器上登入成功,在使用者的瀏覽器上種上一個加密的 cookie,當使用者訪問B伺服器時,檢查有無 session,如果有當然沒問題,如果沒有,就去檢驗 cookie 是否有效,cookie 有效話就在 B 伺服器上重建 session。這種方法其實很有用,如果網站有很多個子頻道,伺服器也不在一個機房,session 沒辦法同步又想做統一登入那就太有用了。
當然還有一種方法就是在負載平衡那一層保持會話,把訪問者綁定在某個伺服器上,那麼所有訪問都在那個伺服器上就不需要 session 同步了。
解析 PHP 中 session 的實現原理以及大網站應用程式應該注意的問題