Session 儲存機制由 `session.save_handler` 決定。預設 `files` 以檔案儲存;`user` 允許完全自定義六個回調函數,支援 Redis、資料庫、Memcached 等集中式儲存。本文對比兩者流程並給出自定義 Handler 完整範本。
session_set_save_handler(
'open', // open($savePath, $sessionName) : bool
'close', // close() : bool
'read', // read($id) : string (返回序列化資料)
'write', // write($id, $data) : bool
'destroy', // destroy($id) : bool
'gc' // gc($maxLifetime) : bool
);
// PHP 5.4+ 可傳入實作 SessionHandlerInterface 的物件
<?php
class FileSessionHandler implements SessionHandlerInterface {
private $savePath;
public function open($savePath, $sessionName): bool {
$this->savePath = $savePath;
if (!is_dir($savePath)) mkdir($savePath, 0777, true);
return true;
}
public function close(): bool { return true; }
public function read($id): string {
$file = $this->savePath . "/sess_$id";
return (string)@file_get_contents($file);
}
public function write($id, $data): bool {
$file = $this->savePath . "/sess_$id";
$fp = @fopen($file, 'w');
if (!$fp) return false;
$ret = fwrite($fp, $data);
fclose($fp);
return $ret !== false;
}
public function destroy($id): bool {
$file = $this->savePath . "/sess_$id";
return @unlink($file);
}
public function gc($maxLifetime): bool {
foreach (glob($this->savePath . "/sess_*") as $file) {
if (filemtime($file) + $maxLifetime < time()) @unlink($file);
}
return true;
}
}
// 註冊
$handler = new FileSessionHandler();
session_set_save_handler($handler, true); // true = 註冊 shutdown function
session_start();
// 正常使用 $_SESSION
?>
掌握 Handler 機制,就能將 Session 從本地檔案解脫,構建高可用、水平擴展的分散式 Session 架構。