我們在前面的文章里面講到session的原理和最佳實踐,感到意猶未盡。現在再來聊下PHP Session用到的幾個相關的函數。
session_start()
session_start() 會創建新會話或者重用現有會話。 如果通過 GET 或者 POST 方式,或者使用 cookie 提交了會話 ID, 則會重用現有會話。
當會話自動開始或者通過 session_start()
手動開始的時候, PHP 內部會調用會話管理器的 open 和 read 回調函數。 會話管理器可能是 PHP 默認的, 也可能是擴展提供的(SQLite 或者 Memcached 擴展), 也可能是通過 session_set_save_handler()
設定的用戶自定義會話管理器。 通過 read 回調函數返回的現有會話數據(使用特殊的序列化格式存儲), PHP 會自動反序列化數據並且填充 $_SESSION
超級全局變量。
要想使用命名會話,請在調用 session_start() 函數 之前調用 session_name() 函數。
如果啟用了 session.use_trans_sid
選項, session_start()
函數會注冊一個內部輸出管理器, 該輸出管理器完成 URL 重寫的工作。
注意:要使用基於 cookie 的會話, 必須在輸出開始之前調用 session_start() 函數。
session_unset()
銷毀當前會話數據。或者$_SESSION = array();
如果要銷毀個別會話數據,可以unset ($_SESSION['varname']);.
session_destroy()
和session_unset()
銷毀所有會話數據不同,session_destroy()
銷毀的是會話本身,此函數一出,當前session就變成垃圾了,等待gc機制去回收它。但是它並不會重置當前會話所關聯的全局變量, 也不會重置會話 cookie。該有的會話數據還是在,只不過“身份”變了而已。如果gc尚且還沒有去回收它,那么它仍然是可以讀取到的,這當然是不願意看到的,因此在session_destroy()
之前往往還要session_unset()
一下。
如果需要再次使用會話變量, 必須重新調用 session_start()
函數。 為了徹底銷毀會話,比如在用戶退出登錄的時候,必須同時重置會話 ID。 如果是通過 cookie 方式傳送會話 ID 的,那么同時也需要 調用 setcookie() 函數來 刪除客戶端的會話 cookie。
下面例子是銷毀數據本身:
// 初始化會話。
// 如果要使用會話,別忘了現在就調用:
session_start();
// 重置會話中的所有變量,銷毀會話數據
$_SESSION = array(); // 或者session_unset()
// 如果要清理的更徹底,那么同時刪除會話 cookie
// 注意:這樣不但銷毀了會話中的數據,還同時銷毀了會話本身
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
// 最后,銷毀會話
session_destroy();
銷毀會話數據$_SESSION = array()
或session_unset()
;銷毀會話本身session_destroy()
;和setcookie()
。session_destroy()
執行后會話就變成垃圾會話,等待gc機制回收。
session_commit()
session_commit()
是 session_write_close()
別稱。和session_start
相反,這是寫和關閉。即保存當前session數據,並且關閉當前會話。為了防止並發的寫session,任何時刻只能允許有一個PHP腳本在操作session,因此,一個腳本一旦session_start
打開session,那么在此腳本終止或者調用session_write_close()
之前,別的任何腳本都不能使用session。在默認情況下腳本結束時會自動寫入和關閉session,但是在腳本執行時間比較長的時候,此腳本就一致占據鎖使得別的腳本無法使用session,因此導致許多錯誤。因此,最佳實踐是,任何session變量,數據的更改(如$_SESSION[xx] = xxx
),都要及時使用session_commit()
保存數據,關閉會話。
session_id ()
session_id() 可以用來獲取/設置 當前會話 ID。 為了能夠將會話 ID 很方便的附加到 URL 之后, 你可以使用常量 SID 獲取以字符串格式表達的會話名稱和 ID。簡單說,就是如果你開啟的是POST/GET方式獲取會話ID,那么這個參數可以通過session.use_trans_sid
設定並在URL中看得見,而在腳本中通過全局變量SID來直接獲取。
//配置
ini_set('session.use_trans_sid', 'sid');
//url中表現
127.0.0.1?sid=xxxxx
//直接獲取
$sid = SID;
如果指定了 session_id ()
參數的值, 則使用指定值作為會話 ID。 必須在調用 session_start()
函數之前調用 session_id()
函數。不同的會話管理器對於會話 ID 中可以使用的字符有不同的限制。 如果當前沒有會話,則返回空字符串("")。
這里有兩點值得注意下:
- 如果使用 cookie 方式傳送會話 ID,並且指定了 id 參數, 在調用 session_start() 之后都會向客戶端發送新的 cookie, 無論當前的會話 ID 和新指定的會話 ID 是否相同
- 在通過session_id ($id )切換當前會話ID之前,需要通過
session_commit()
來關閉上一個會話,否則當前會話還是原來的
更多的函數可以參看PHP官網或者手冊。