设为首页 收藏本站
查看: 847|回复: 0

[经验分享] PHP保持SESSION问题以及由SESSION性能引发的一些思考

[复制链接]

尚未签到

发表于 2018-12-22 08:32:03 | 显示全部楼层 |阅读模式
PHP中如何设置SESSION?  搭建好PHP的开发环境后,通过phpinfo()可以查看到与SESSION有关的部分包括:
  SESSION模块,在PHP V5.2.9版本中,一共有25个变量。其中,平时设置中常会用到的几个有:
  session.cookie_lifetime        设置存储SESSIONID的cookie过期时间
  session.name                SESSION的COOKIE名称,默认为PHPSESSID
  session.save_handler        SESSION的存储方式,默认为FILE
  session.save_path            Fedora下面默认存储在/var/lib/php/session
  session.gc_probability
  session.gc_divisor
  session.gc_maxlifetime        这三个选项用来处理GC机制发生的机率
  session.cache_limiter    (nocache,private,private_no_expire,public)
  session.cache_expire    这两个选项是用来缓存SESSION的页面
  先来考虑第一个问题,SESSION多久会过期,他是如何过期的?如果要在PHP程序中使用SESSION,一定要先引用session_start(),这个函数一执行,就会在SESSION的存储目录(如果使用了file handler)生成一个SESSION文件,里面内容是空的,同时浏览器会见里一个name为PHPSESSID的cookie,里面存储着一个hash出来的SESSION的名字。
  SESSION的过期依赖于一个垃圾回收机制(Garbage Collection),SESSION创建后作为一个文件存放在服务器上,客户端脚本每访问一次SESSION中的变量,SESSION文件的访问时间就会进行更新。每次访问都是根据客户端存储的SESSIONID去请求服务器中存储的唯一的SESSION,当客户端的cookie过期后,就无法知道要访问的是哪一个SESSION,尽管此时服务器上的SESSION文件还没有被过期收回,这样就会造成服务器资源的浪费。
  但是同时,如果我们希望用户的session马上过期的话,我们就可以通过设置cookie的办法来实现。SESSION的回收是在每次访问页面的时候进行的,回收的机率由session.gc_probability,session_gc_divisor指定,默认士1/100。如果设置为1,则每次超过了SESSION的生存周期去访问的话,SESSION一定会被回收。
  两种需求:1、保持SESSION不过期或延长SESSION过期时间;2、使SESSION立即过期。
  1、保持SESSION不过期和延长SESSION过期时间非常必要,特别是在内部应用系统中或者有很大的表单的时候。想想你的老板在填写一个表单,刚好碰上午饭时间,留着这个表单等吃饭回来,填写完剩余的内容,提交后他看到什么,一般来说都是一个登录界面。想要提高用户体验,关键是要让老板的表单不出问题,我们就必须延长SESSION的生存周期。
  保持SESSION不过期和延长SESSION过期时间,可以通过设置session.gc_maxlifetime来实现,不过首先需要保证客户端的cookie不会在gc执行回收之前失效。通过设置一个较长的gc_maxlifetime可以实现延长session的生存周期,可是对于不是所有请求都会保持很久的应用来说,这么做对于服务器配置显然不是一个最佳的选择。
  我们知道SESSION的回收机制是根据SESSION文件的最后访问时间来判断的,如果超过了maxlifetime,则根据回收机率进行回收。所以我们只需要定期的去访问一下SESSION就可以了,而这可以通过刷新页面来实现,根据这个思路,解决的方法就有了。
  通过JS定期的去访问页面;
  利用Iframe定期的刷新页面;
  直接利用程序发送HTTP请求,这样就可以避免在页面中嵌入其他的元素;
  下面是利用JS发送请求实现的保持SESSION不过期的实现方法,这样我们就只需要在需要SESSION保持长时间的页面(比如大表单页面)。
  
  function keepMeAlive(imgName){
  myImg = document.getElementById(imgName);
  if(myImg) myImg.src = myImg.src.replace(/\?.*$/, '?' + Math.random());
  }
  window.setInterval("keepMeAlive('phpImg');", 4000);
  

    其中URL后加入一个随机数是为了避免这个链接的请求被浏览器缓存。
  2、使SESSION立即过期的方法就比较多了,我们可以session_destroy(),也可以用上面的思路,请求一个session_destroy的页面。
  SESSION安全吗?
  PHP的手册中明确写出:SESSION并不能保证储存在SESSION中的信息一定只能被他的创建者所看到。
  如果想要安全的处理一些远程的操作,那么HTTPS是唯一的选择。最基本的,不要认为一个用户信息在SESSION中存在就认为这个用户一定就是他本人,虽然SESSION中的信息会给你他已经经过了用户名和密码验证的假象。所以,如果需要做一些修改密码或者类似的事情的时候,让用户重新输入密码是一个比较好的选择。
  早期的Apache版本并没有采用COOKIE的方式来存储PHPSESSID,而是采用的URL-rewrite,也就是每个URL后面都会加上PHPSESSID=来表明它属于那个激活的SESSION,新版的Apache已经将这个属性设置为默认关闭。
  session.use_trans_id = 0;
  所以从这个意义上来讲,延长SESSION的时间过长或者保持SESSION一直在线对于安全来说始终不是一件好事情。终极的解决办法就是用户提交跳转到登录窗口,登录后又能够回到填写页面,并且所有的数据都还在。这个的实现方式现在用Ajax来解决应该没什么困难,每隔一定时间就把当前的用户数据POST到一个存储位置,不管是XML或者JSON。
  拾遗:
  对于客户端不支持JavaScript的情况可以采用的方法:
  1、写一个浮层,显示在最顶层,如果用户未禁用JS,则让浮层消失;
  2、将所有的INPUT都设置为disable,然后再用JS设置为enabled;
  以上这两种方式都是在JS被禁用的时候,所有功能都不能用,如何在JS被禁用的情况下使我们的应用仍然正常工作,这个貌似就比较困难。实现这个的所花的时间和所收到的效果大家要权衡一下。
  参考资料
  1、SESSION Security                http://uk2.php.net/manual/en/session.security.php
  2、WIKI    SESSION                    http://en.wikipedia.org/wiki/Session
  3、SESSION(computer science)    http://en.wikipedia.org/wiki/Session_(computer_science)
  4、Http Cookie                    http://en.wikipedia.org/wiki/HTTP_cookie
  5、PHP.net SESSION                http://cn.php.net/manual/en/intro.session.php
  6、OSSP mm                        http://www.ossp.org/pkg/lib/mm/


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-654227-1-1.html 上篇帖子: PHP集成开发环境 Zend Studio Enterprise v5.5.0完美版 下篇帖子: php获取客户端和服务器端ip
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表