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