Loading... # [关于session和memcache的若干问题](https://blog.p2hp.com/archives/511) 一直以来,由于php本身的session机制不能跨机,令很多phper感到不爽,现在流行的解决方案主要有: 1)使用数据库来实现 2)自己写server端,通过改写session处理函数来请求 3)使用nfs等跨机存储来保存session 4)使用memcache来保存 5)使用zend platform提供的解决方案 其中的1-4都是通过改用可以跨机的储存机制,再使用session_set_save_handler()来实现,5是zend公司的商业产品(不过据之前在使用的同事反映,效果不太满意),以上的方案,各有利弊,不在本文讨论范围 无论是用memcache,还是db,nfs,其原理是一样的,都是通过session_set_save_handler函数来改变默认的处理方式,通过指定回调函数来自定义处理,可以参考手册的session_set_save_handler()函数部分,有例子,比较容易明白 以下是一些我在使用memcache来实现时的一些记录: 1)使用类来实现时,各回调函数都定义为静态方法,在类的构造中使用session_set_save_handler注册回调函数, 如: session_set_save_handler( array(\'memSession\', \'open\'), array(\'memSession\', \'close\'), array(\'memSession\', \'read\'), array(\'memSession\', \'write\'), array(\'memSession\', \'destroy\'), array(\'memSession\', \'gc\') ); memSession为类名,要使用session,则先new memSession,再session_start(); 2)生存期和垃圾回收 memCache的set命令有生存期,即使用set命令添加值时,可加上lifetime,此时间可以作为session的生存期,用户在此时间内没有动作,则会失效,但有动作则不会失效(因为每一个脚本结束时,都会执行write和close,此时lifetime就会被更新了),当然,如果使用cookie传递SID,则控制SESSION生存期可以用:ini_set(\'session.cookie_lifetime\',time)来设定,这其实是控制cookie的有效时间,如果session赖以生存的cookie消失了,当然session也就活不了,使用cookie_lifetime来控制的话,无论有无动作,都将在指定的时间后过时 gc是指垃圾回收,在session中是指清理过期的session数据,影响的参数有: session.gc_maxlifetime 被视为垃圾前的生存期,超过此时间没有动作,数据会被清走 注意的是,gc不是每次启动会话都会被执行,而是由session.gc_probability 和 session.gc_divisor的比率决定的 结论:控制SESSION的生存期有几种方法 一是cookie_lifttime,这种方式无论有无动作,都会在指定时间内销毁 二是在read中根椐保存时间控制,此方法在有动作时时间会一直有效 三设定session.gc_probability 和 session.gc_divisor的比率为1(即每次会话都会启用gc),再设定gc.maxlifetime来指定生存期,此方法也是在用户有动作时时间一直有效 3)回调函数的执行时机 open 在运行session_start()时执行 read 在运行session_start()时执行,因为在session_start时,会去read当前session数据并写入$_SESSION变量 destroy 在运行session_destroy()时执行 close 在脚本执行完成或调用session_write_close() 或 session_destroy()时被执行,即在所有session操作完成后被执行 gc 执行概率由session.gc_probability 和 session.gc_divisor的值决定,时机是在open,read之后,即session_start会相继执行open,read和gc write 此方法在脚本结束和使用session_write_close()强制提交SESSION数据时执行 结论: session_start //执行open(启动会话),read(读取session数据至$_SESSION),gc(清理垃圾) 脚本中间所有对$_SESSION的操作均不会调用这些回调函数 session_destroy //执行destroy,销毁当前session(一般是删除相应的记录或文件),相应地,此回调函数销毁的只是session的数据,但此时 var_dump一下$_SESSION变量,仍然有值的,但此值不会在close后被write回去 session_write_close() //执行write和close,保存$_SESSION至存储,如不手工使用此方法,则会在脚本结束时被自动执行 清晰了以上信息,将对你清楚了解SESSION的工作原理有很大的帮助... 4)直接使用memcache作session处理 在我写了一系列的memcache来保存session的代码后,无意中发现,可以直接在php.ini中设定使用memcache作为session处理,而无须另外编码,方法是: 修改php.ini中的以下值 session.save_handler = memcache session.save_path = \'tcp://host1:11211\' #有多个时直接用","分隔即可 如果只想在特定的应用里使用memcache储存session,可以使用ini_set的方法对以上两个参数进行设定 要测试一下是否真正用上了memcache,可以先捕足到使用的PHPSESSID,再作为KEY用memcach去读一下,就清楚了 最后修改:2023 年 08 月 07 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏