(PHP 4, PHP 5, PHP 7, PHP 8)
session_set_save_handler — 設(shè)置用戶自定義會(huì)話存儲(chǔ)函數(shù)
$open
,$close
,$read
,$write
,$destroy
,$gc
,$create_sid
= ?,$validate_sid
= ?,$update_timestamp
= ?可以使用下面的方式來注冊自定義會(huì)話存儲(chǔ)函數(shù):
$sessionhandler
, bool $register_shutdown
= true
): boolsession_set_save_handler() 設(shè)置用戶自定義 會(huì)話存儲(chǔ)函數(shù)。 如果想使用 PHP 內(nèi)置的會(huì)話存儲(chǔ)機(jī)制之外的方式, 可以使用本函數(shù)。 例如,可以自定義會(huì)話存儲(chǔ)函數(shù)來將會(huì)話數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫。
本函數(shù)有 2 種原型:
sessionhandler
實(shí)現(xiàn)了 SessionHandlerInterface, SessionIdInterface(可選) 和/或 SessionUpdateTimestampHandlerInterface 接口的對象, 例如 SessionHandler。
register_shutdown
將函數(shù) session_write_close() 注冊為 register_shutdown_function() 函數(shù)。
open(string $savePath, string $sessionName)
實(shí)現(xiàn)了以下簽名的 callable 回調(diào):
$savePath
, string $sessionName
): bool
open 回調(diào)函數(shù)類似于類的構(gòu)造函數(shù),
在會(huì)話打開的時(shí)候會(huì)被調(diào)用。
這是自動(dòng)開始會(huì)話或者通過調(diào)用 session_start() 手動(dòng)開始會(huì)話
之后第一個(gè)被調(diào)用的回調(diào)函數(shù)。
此回調(diào)函數(shù)操作成功返回 true
,反之返回 false
。
close
close 回調(diào)函數(shù)類似于類的析構(gòu)函數(shù)。
在 write 回調(diào)函數(shù)調(diào)用之后調(diào)用。
當(dāng)調(diào)用 session_write_close() 函數(shù)之后,也會(huì)調(diào)用 close 回調(diào)函數(shù)。
此回調(diào)函數(shù)操作成功返回 true
,反之返回 false
。
read
實(shí)現(xiàn)了以下簽名的 callable 回調(diào):
$sessionId
): string如果會(huì)話中有數(shù)據(jù),read 回調(diào)函數(shù)必須返回將會(huì)話數(shù)據(jù)編碼(序列化)后的字符串。 如果會(huì)話中沒有數(shù)據(jù),read 回調(diào)函數(shù)返回空字符串。
在自動(dòng)開始會(huì)話或者通過調(diào)用 session_start() 函數(shù)手動(dòng)開始會(huì)話之后,PHP 內(nèi)部調(diào)用 read 回調(diào)函數(shù)來獲取會(huì)話數(shù)據(jù)。 在調(diào)用 read 之前,PHP 會(huì)調(diào)用 open 回調(diào)函數(shù)。
read 回調(diào)返回的序列化之后的字符串格式必須與 write
回調(diào)函數(shù)保存數(shù)據(jù)時(shí)的格式完全一致。
PHP 會(huì)自動(dòng)反序列化返回的字符串并填充 $_SESSION 超級(jí)全局變量。
雖然數(shù)據(jù)看起來和 serialize() 函數(shù)很相似,
但是需要提醒的是,它們是不同的。
請參考: session.serialize_handler。
write
實(shí)現(xiàn)了以下簽名的 callable 回調(diào):
$sessionId
, string $data
): bool
在會(huì)話保存數(shù)據(jù)時(shí)會(huì)調(diào)用 write
回調(diào)函數(shù)。
此回調(diào)函數(shù)接收當(dāng)前會(huì)話 ID 以及 $_SESSION 中數(shù)據(jù)序列化之后的字符串作為參數(shù)。
序列化會(huì)話數(shù)據(jù)的過程由 PHP 根據(jù) session.serialize_handler 設(shè)定值來完成。
序列化后的數(shù)據(jù)將和會(huì)話 ID 關(guān)聯(lián)在一起進(jìn)行保存。
當(dāng)調(diào)用 read
回調(diào)函數(shù)獲取數(shù)據(jù)時(shí),所返回的數(shù)據(jù)必須要和
傳入 write
回調(diào)函數(shù)的數(shù)據(jù)完全保持一致。
PHP 會(huì)在腳本執(zhí)行完畢或調(diào)用 session_write_close() 函數(shù)之后調(diào)用此回調(diào)函數(shù)。
注意,在調(diào)用完此回調(diào)函數(shù)之后,PHP 內(nèi)部會(huì)調(diào)用 close
回調(diào)函數(shù)。
注意:
PHP 會(huì)在輸出流寫入完畢并且關(guān)閉之后 才調(diào)用 write 回調(diào)函數(shù), 所以在 write 回調(diào)函數(shù)中的調(diào)試信息不會(huì)輸出到瀏覽器中。 如果需要在 write 回調(diào)函數(shù)中使用調(diào)試輸出, 建議將調(diào)試輸出寫入到文件。
destroy
實(shí)現(xiàn)了以下簽名的 callable 回調(diào):
$sessionId
): bool
當(dāng)調(diào)用 session_destroy() 函數(shù),
或者調(diào)用 session_regenerate_id() 函數(shù)并且設(shè)置 destroy 參數(shù)為 true
時(shí),
會(huì)調(diào)用此回調(diào)函數(shù)。此回調(diào)函數(shù)操作成功返回 true
,反之返回 false
。
gc
實(shí)現(xiàn)了以下簽名的 callable 回調(diào):
$lifetime
): bool
為了清理會(huì)話中的舊數(shù)據(jù),PHP 會(huì)不時(shí)的調(diào)用垃圾收集回調(diào)函數(shù)。
調(diào)用周期由 session.gc_probability
和 session.gc_divisor 參數(shù)控制。
傳入到此回調(diào)函數(shù)的 lifetime 參數(shù)由 session.gc_maxlifetime 設(shè)置。
此回調(diào)函數(shù)操作成功返回 true
,反之返回 false
。
create_sid
實(shí)現(xiàn)了以下簽名的 callable 回調(diào):
需要新的會(huì)話 ID 時(shí),執(zhí)行此回調(diào)函數(shù)。 它被調(diào)用時(shí)不會(huì)傳入?yún)?shù),其返回值應(yīng)該是一個(gè)字符串格式的、有效的 session ID。
validate_sid
實(shí)現(xiàn)了以下簽名的 callable 回調(diào):
$key
): bool
開啟 session.use_strict_mode 后,
當(dāng)啟動(dòng)一個(gè) session 時(shí),提供了 session ID 后會(huì)執(zhí)行此回調(diào)。
參數(shù) key
是待驗(yàn)證的 session ID。
如果該 ID 的 session 已經(jīng)存在,則為有效 session ID。
成功時(shí)返回值應(yīng)當(dāng)為 true
,失敗時(shí)為 false
。
update_timestamp
實(shí)現(xiàn)了以下簽名的 callable 回調(diào):
$key
, string $val
): bool
更新 session 時(shí)執(zhí)行此回調(diào)。
參數(shù) key
是 session ID;參數(shù) val
是 session 的數(shù)據(jù)。
成功時(shí)返回值應(yīng)當(dāng)為 true
,失敗時(shí)為 false
。
成功時(shí)返回 true
, 或者在失敗時(shí)返回 false
。
示例 #1 自定義會(huì)話管理器: 完整代碼請參見 SessionHandlerInterface。
這里僅列出了調(diào)用方式,完整代碼請參見 SessionHandlerInterface。
這里使用了 session_set_save_handler() 函數(shù)的 OOP 原型 并且使用第二個(gè)參數(shù)來注冊 shutdown 函數(shù)。 當(dāng)將對象注冊為會(huì)話保存管理器時(shí),建議使用這種方式。
<?php
class MySessionHandler implements SessionHandlerInterface
{
// 在這里實(shí)現(xiàn)接口
}
$handler = new MySessionHandler();
session_set_save_handler($handler, true);
session_start();
// 現(xiàn)在可以使用 $_SESSION 保存以及獲取數(shù)據(jù)了
在對象銷毀之后才會(huì)調(diào)用
write
和 close
回調(diào)函數(shù),
所以,在這兩個(gè)回調(diào)函數(shù)中不可以使用對象,也不可以拋出異常。
如果在函數(shù)中拋出異常,PHP 既不會(huì)捕獲它,也不會(huì)跟蹤它,
這樣會(huì)導(dǎo)致程序異常終止。
但是對象析構(gòu)函數(shù)可以使用會(huì)話。
可以在析構(gòu)函數(shù)中調(diào)用 session_write_close() 函數(shù)來解決這個(gè)問題。 但是注冊 shutdown 回調(diào)函數(shù)才是更加可靠的做法。
如果會(huì)話在腳本結(jié)束后關(guān)閉,對于某些 SAPI 而言,當(dāng)前工作目錄可能已經(jīng)被改變。 可以調(diào)用 session_write_close() 函數(shù)在腳本執(zhí)行結(jié)束之前關(guān)閉會(huì)話。