百科狗-知识改变命运!
--

session_set_save_handler() - php 会话函数session

梵高1年前 (2023-11-21)阅读数 12#技术干货
文章标签函数

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]): bool

session_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()

session_set_save_handler() - php 会话函数session

当需要新的会话 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

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)