PHP之session机制和优化

9 篇文章 0 订阅
7 篇文章 0 订阅

        本文说一说PHP中的Session机制和优化的话题。

        默认情况下,我们是直接使用$_SESSION来操作会话,并且以文件的形式保存,一个会话对应一个文件。如果单个目录下存储太多会话文件影响读取效率,可以通过配置多级目录存储。默认使用文件保存会话,存在单机情况,不能部署应用群集的方式来扩展PHP应用。但是使用memcache和redis等扩展,通过配置可以直接把会话保存到memcache和redis中,并且不需要改变之前的使用方式,直接使用$_SESSION,这样能方便地扩展集群,并且简单高效。

        PHP Session的启动,可以配置为是否自动启动,是的话,每个请求一开始,就可以直接使用$_SESSION了,$_SESSION里的内容已经(从文件 、memcache、redis中)取出来了;如果否,程序中则要调用session_start来启动。想要更多的控制权,就不要自动启动,比如一些页面不需要会话的,就不应启动会话(因为启动了又不用,还要浪费会话读取的功夫)。

        进一步探究,PHP提供了一套机制:session_set_save_handler注册回调方法和实现SessionHandlerInterface接口(5.4版本后支持),这两者使用差别不是很多,随意选择,都要实现open, read, close,write,gc,destroy这几个方法。当session_start()时,调用open和read方法,把会话读取到$_SESSION变量中,用户就可以在当前请求中,存取$_SESSION变量。在程序执行完后,在输出流结束以后,在有 register_shutdown_function() 方法执行以后,执行write和close方法,将会话内容写回到存储系统。这样我们就可以自定义把会话保存到数据库中,或者保存到memcache/redis等缓存系统中。

        根据上面PHP会话机制的了解,有如下主要实践,也是优化方案:

        1. 把会放的启动控制放到控制器(基类控制器、子类控制器、甚至控制器中的方法),让控制器决定是否使用会话。

        2. 不要直接使用$_SESSION变量,而是封成方法,比如sget/sset/sdel来获取/保存/删除会话内容,因为直接使用$_SESSION无法进一步控制或优化。

        3. 实际上网站在使用会话时,大部分都是读取操作,而不会修改会话内容,因此可采取只读而不回写策略,能减少一次网络操作。需要结合第2点,当会话操作时,维护一个变量$isChange,读会话时不需要设置$isChange,设置或删除会话时$isChange=true;当PHP执行session方法write时,对$isChange进行判断,有变更时进行写回,没有变更时,直接返回。

     

       进一步的考虑是,把session的内容保存到cookie中,并进行加密。这样的好处是,不需要为session消耗太多服务器资源,坏处是,增加稍许的网络流量,总得来说值得使用。cookie尽量不要保存太多数据,可结合数据库或缓存系统,比如只把登录所需要的用户角色权限相关数据作为会话保存到cookie中,而与购物车,其它临时数据等存到缓存。

        session数据的编码解码,简单地可使用serialize/unserialize/json_encode/json_decode进行编码解码。而加解密按需选取一个加密算法即可。

        使用cookie会话一般都要ob_start()开始输出缓冲区,注意不要在在关闭缓冲区或输出流关闭后再设置cookie,或者输出内容后再设置cookie,否则会报:Cannot modify header information - headers already sent。如果是在程序结束后,再调用session的write方法设置cookie,在遇到输出图形校验码或比较大的文件内容等情况会出错。一种解决方法在设置会话时立即输出header,然后再输出其它内容,而不是等到执行会话的write方法时再输出cookie的header信息。

  如果把session放到cookie中,会增大header头部数据量,通过nginx等反向代理转发时,可能需要调整转发的buffer.


        根据以上的机制和思路,简单实现了关于会话的封装,可参考github中的session目录:https://github.com/frogluo/php/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值