IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

关于session和memcache的若干问题

PHPec 2009-10-21 22:15:16 累计浏览 5,262 次
本机暂存

    一直以来,由于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去读一下,就清楚了

同分类推荐文章

  1. Vibe新开源项目 - Vaala AI Gateway (2026-05-17 02:10:19)
  2. SmartPerfetto 架构文章 Q&A:8 个深度技术问答 (2026-04-10 11:00:00)
  3. 让 AI 把我的 PHP 博客重写成 Go (2026-03-27 18:33:54)

查看更多 后端 文章 →

建议继续学习

  1. 使用gettext来支持PHP的多语言 (累计阅读 39,181)
  2. WordPress插件开发 -- 在插件使用数据库存储数据 (累计阅读 29,083)
  3. Paypal接口详细代码(PHP版,非API接口) (累计阅读 19,340)
  4. 浅析http协议、cookies和session机制、浏览器缓存 (累计阅读 17,302)
  5. 我的PHP,Python和Ruby之路 (累计阅读 13,061)
  6. include(“./file.php”)和include(“file.php”)区别 (累计阅读 12,720)
  7. 15个最好的免费开源电子商务平台 (累计阅读 12,461)
  8. Redis消息队列的若干实现方式 (累计阅读 12,000)
  9. 到底什么是MVC? (累计阅读 11,687)
  10. Rolling cURL: PHP并发最佳实践 (累计阅读 11,421)