对于访问量大的网站,用默认的 Session 存储方式(以文件存储)不适合,因为文件的 I/O 开销会非常大,另外 Session 机制本身使 Session 不能跨机访问,在 Web 集群中无法达到跟踪用户的目的。
此时可以考虑使用 NFS 或 SAMBA 等共享技术把 Session 保存到其他服务器中。
也可以使用数据库(使用普通存储引擎或者 Memory 引擎)、内存服务器(结合关系型数据库)等方式来存储 Session,需要使用 session_get_save_handler() 函数来设置用户自定义会话存储函数,以代替默认的 php.ini 中的 session.save_handler 配置,该配置的默认值是:
session.save_handler = files
要使用自定义的方式处理 Session 的存储时需要修改该配置:
session.save_handler = user
session_get_save_handler() 方法的结构是:
bool session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc [, callable $create_sid ] )
在 PHP 5.4 以后还可以使用以下方式:
bool session_set_save_handler ( SessionHandlerInterface $sessionhandler [, bool $register_shutdown = true ] )
其中接口 SessionHandlerInterface 如下:
SessionHandlerInterface { /* 方法 */ abstract public bool close ( void ) abstract public bool destroy ( string $session_id ) abstract public bool gc ( int $maxlifetime ) abstract public bool open ( string $save_path , string $name ) abstract public string read ( string $session_id ) abstract public bool write ( string $session_id , string $session_data ) }
以第 1 种方式为例,它有 6 个回调函数作为必选参数,分别代表了 Session 生命周期的 6 个过程,通过自定义这个函数来设置 Session 生命周期中的每个过程。
session_set_save_handler 的回调函数说明:
回调函数 | 执行时机 | 描述 |
open | 调用 session_start() 时执行 | 该函数需要声明两个参数,系统会自动将 php.ini 中 session.save_path 选项的值传递给第一个参数,将 Session Name 传递给第二个参数,返回 True 则自动向下执行 |
close | 调用 session_write_close() 或 session_destroy() 时执行 | 不需要参数,在所有的 session 操作完之后被执行。如果不需要处理,直接返回 True 即可。 |
read | 调用 session_start() 时执行 | 开启会话时,会去根据 Cookie 或 URL 中的 Session ID 来 read 当前 Session 数据,该函数需要一个参数,系统会自动将 Session ID 传递给该函数,并且通过 Session ID 获取对应的 $_SESSION 中的数据。该函数返回当前的会话信息 $_SESSION |
write | 调用 session_write_close() 时执行 | 需要声明两个参数,分别是 Session ID 和 串行化后的 Session 信息字符串。在对 Session 变量进行赋值时,通过 Session ID 找到相应的存储位置,并将信息写入。存储成功后返回 True 继续向下执行。 |
destroy | 调用 session_destroy() 时执行 | 需要一个参数,系统会自动将 Session ID 传给该函数,删除当前用户对应的 Session 文件 以及释放 session |
gc | 调用 session_start() 时执行 | 需要声明一个参数,系统会将 php.ini 中的 session.gc_maxlifetime 选项的值传给该参数,用于删除超过该值代表的时间的 Session 文件。返回 True 则会自动向下执行。 |
注意:调用 session_destroy() 销毁的是 Session 文件和数据;但是在回调函数中,销毁的只是 Session 的数据,如果此时输出 $_SESSION,仍然有值,但是该值不会在回调函数 close 执行时再被写回去。
实际使用的例子参见《Memcached 笔记与总结(9)Memcached 与 Session》