session_set_save_handler() - php 会话函数session
session_set_save_handler()
(PHP 4, PHP 5, PHP 7)
设置用户自定义会话存储函数
说明
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自 PHP 5.4 开始,可以使用下面的方式来注册自定义会话存储函数:
session_set_save_handler(object $sessionhandler[,bool $register_shutdown=TRUE
]): boolsession_set_save_handler()设置用户自定义会话存储函数。如果想使用 PHP 内置的会话存储机制之外的方式,可以使用本函数。例如,可以自定义会话存储函数来将会话数据存储到数据库。
参数
本函数有 2 种原型:
$sessionhandler实现了SessionHandlerInterface,SessionIdInterface和/或SessionUpdateTimestampHandlerInterface接口的对象,例如SessionHandler。自 PHP 5.4 之后可以使用。
$register_shutdown将函数session_write_close()注册为register_shutdown_function()函数。
或者open(string $savePath, string $sessionName)
open 回调函数类似于类的构造函数,在会话打开的时候会被调用。这是自动开始会话或者通过调用session_start()手动开始会话之后第一个被调用的回调函数。此回调函数操作成功返回TRUE
,反之返回FALSE
。
close()
close 回调函数类似于类的析构函数。在 write 回调函数调用之后调用。当调用session_write_close()函数之后,也会调用 close 回调函数。此回调函数操作成功返回TRUE
,反之返回FALSE
。
read(string $sessionId)
如果会话中有数据,read 回调函数必须返回将会话数据编码(序列化)后的字符串。如果会话中没有数据,read 回调函数返回空字符串。
在自动开始会话或者通过调用session_start()函数手动开始会话之后,PHP 内部调用 read 回调函数来获取会话数据。在调用 read 之前,PHP 会调用 open 回调函数。
read 回调返回的序列化之后的字符串格式必须与$write回调函数保存数据时的格式完全一致。 PHP 会自动反序列化返回的字符串并填充$_SESSION超级全局变量。虽然数据看起来和serialize()函数很相似,但是需要提醒的是,它们是不同的。请参考:session.serialize_handler。
write(string $sessionId, string $data)
在会话保存数据时会调用$write回调函数。此回调函数接收当前会话 ID 以及$_SESSION中数据序列化之后的字符串作为参数。序列化会话数据的过程由 PHP 根据session.serialize_handler设定值来完成。
序列化后的数据将和会话 ID 关联在一起进行保存。当调用$read回调函数获取数据时,所返回的数据必须要和传入$write回调函数的数据完全保持一致。
PHP 会在脚本执行完毕或调用session_write_close()函数之后调用此回调函数。注意,在调用完此回调函数之后,PHP 内部会调用$close回调函数。Note:
PHP 会在输出流写入完毕并且关闭之后才调用 write 回调函数,所以在 write 回调函数中的调试信息不会输出到浏览器中。如果需要在 write 回调函数中使用调试输出,建议将调试输出写入到文件。
destroy($sessionId)
当调用session_destroy()函数,或者调用session_regenerate_id()函数并且设置 destroy 参数为TRUE
时,会调用此回调函数。此回调函数操作成功返回TRUE
,反之返回FALSE
。
gc($lifetime)
为了清理会话中的旧数据,PHP 会不时的调用垃圾收集回调函数。调用周期由session.gc_probability和session.gc_divisor参数控制。传入到此回调函数的 lifetime 参数由session.gc_maxlifetime设置。此回调函数操作成功返回TRUE
,反之返回FALSE
。
create_sid()
当需要新的会话 ID 时被调用的回调函数。回调函数被调用时无传入参数,其返回值应该是一个字符串格式的、有效的会话 ID。
返回值
成功时返回TRUE
,或者在失败时返回FALSE
。
更新日志
版本 | 说明 |
---|---|
7.0.0 | 新增可选参数$validate_sid和$update_timestamp。 |
5.5.1 | 新增可选参数$create_sid。 |
5.4.0 | 新增用来实现自定义会话处理器的接口SessionHandlerInterface;新增 PHP 内部会话处理器类:SessionHandler。 |
范例
自定义会话管理器:完整代码请参见SessionHandlerInterface。
下列代码适用于 PHP 5.4.0 及以上版本。这里仅列出了调用方式,完整代码请参见SessionHandlerInterface。
这里使用了session_set_save_handler()函数的 OOP 原型并且使用第二个参数来注册 shutdown 函数。当将对象注册为会话保存管理器时,建议使用这种方式。
After spend so many time to understand how PHP session works with database and unsuccessful attempts to get it right, I decided to rewrite the version from our friend stalker. //Database CREATE TABLE `Session` ( `Session_Id` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `Session_Expires` datetime NOT NULL, `Session_Data` text COLLATE utf8_unicode_ci, PRIMARY KEY (`Session_Id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8_unicode_ci; SELECT * FROM mydatabase.Session;
The "binary" data that is in the session data appears to surround class/object names, and if you pass your session data through a function to sanitize it for SQL injection, you may indeed run in to problems. For example, using the PDO::quote() function to prepare the data for injection (in my case for SQLite3), it was stopping short as soon as it encountered the first bit of binary data, causing my session information to be corrupted. This change *must* have happened somewhere in the 5.2 series, because I just started encountering this problem recently on a code base that had been tested & working on earlier versions of PHP 5.2. This may in fact be a bug - I have not yet checked... but beware, and perhaps using base64 to encode/decode your session data is a good thing to do just to be sure (though you are now left unable to visually inspect serialized session information at the storage level which is a rather big problem for on-the-fly debugging of sessions).
For some people it might be important to know, that if the standard session handler has been overwritten with session_set_save_handler, no locking is working anymore (between session_read and session_write). The following might happen: script "A" start . read session data . . script "B" start . read session data running (30secs) add session data . write sesion data . script "B" stop write session data . script "A" stop . If a script "A" runs for a long time (say 30secs) the same user might start another script "B", which also uses a session. Script "B" will start and read session data, even though script "A" is still running. Because script "B" is much faster it will finish its work and write back its session data before script "A" has ended. Now script "A" ends and overwrites all of script "B"'s session data. If you DON'T use session_set_save_handler, this cannot happend, because in this case, PHP will not start script "B" until script "A" ends.
Note that if session.auto_start is set to On in the php.ini, your session_set_save_handler will return false as the session has already been initialized. If you are finding that your code works OK on one machine but doesn't work on another, check to see if session.auto_start is set to On
I write a class that unites whole handler functionality. It's not even needed to save instances of this class in variables. Just add a row: and the handler will rule the sessions ;-)
session_set_save_handler is used before session_start.if your session is setted as auto start. it will return FALSE value.so you need add session_write_close() before session_set_save_handler to cancel the session's auto start.it likes this:
鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com
图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!