PHP中的Session

风行水上 @ 2014-12-19 13:19:38
标签:

    Session是什么

    小毛贼发问“天王盖地虎”,对方回答“宝塔镇河妖”。这是暗号,用来辨识身份。

    哨兵发问“口令”,来人回答“长江”,哨兵回应“黄河”。这是口令,用来辨识身份。

    持有一张“通行证”,就可以通过检查,这也是用来辨识身份。

    辨识的过程是确认两个实体是否可以“关联”在一起。很多地方,我们需要验证两个实体是不是联系在一起的。

    对于HTTP来说,就是服务器端和客户端是不是处在一个会话过程(Session)当中。

    为此,当客户端第一次向服务器发出请求时,服务器可以给客户端发配一个令牌。之后的通信过程中,客户端出示这个令牌,服务器就可以辨识客户端了。

    这个令牌通常是一个随机字符串。在服务器段,这个令牌可以绑定一组数据,用于在不同的请求之间维护状态和数据。

    Session是如何工作的

    Session像是一个令牌。那么令牌就需要挂在身上。对于HTTP请求来说,这个身上,通常是有三种可能的位置

    • Query String
    • Cookie
    • Request Header

    令牌是给HTTP请求用的,不是给浏览器的用户用的,对用户来说,是一个相对隐形的东西,因此实践中采用Cookie传递的方式比较多。

    Cookie本质上也是Request Header的一部分。

    Session 数据如何清理

    • ``session.gc_probability`
    • session.gc_divisor
    • session.gc_maxlifetime
    • PHP程序每次初始化Session,即(session_start)时,尝试进行垃圾清理。
    • session.gc_probability/session.gc_probability的概率启动清理进程。
    • 清理对象是lifetime大于session.gc_maxlifetime
    • 对于默认的文件系统Session存储来说,就是判断文件的mtime,而不是atime

    PHP的默认设置有可能是 session.gc_probability=1 session.gc_divisor=100,即1%的概率。

    有时也会看到默认设置是 session.gc_probability=0 session.gc_divisor=1000,即禁用了自动清理。这种情况下,可能系统安装了另外一个crontab来进行Session垃圾清理。(参考:http://www.appnovation.com/blog/session-garbage-collection-php )。

    cat /etc/cron.d/php5                                                                                                                                                                                       
    # /etc/cron.d/php5: crontab fragment for php5                                                                                                                                                                                             
    #  This purges session files older than X, where X is defined in seconds                                                                                                                                                                  
    #  as the largest value of session.gc_maxlifetime from all your php.ini                                                                                                                                                                   
    #  files, or 24 minutes if not defined.  See /usr/lib/php5/maxlifetime                                                                                                                                                                    
                                                                                                                                                                                                                                              
    # Look for and purge old sessions every 30 minutes                                                                                                                                                                                        
    09,39 *     * * *     root   [ -x /usr/lib/php5/maxlifetime ] && [ -x /usr/lib/php5/sessionclean ] && [ -d /var/lib/php5 ] && /usr/lib/php5/sessionclean /var/l                                                                           
    ib/php5 $(/usr/lib/php5/maxlifetime)    
    

    根据文件"/usr/lib/php5/sessionclean"的内容,外部清楚进程是判断Session文件的ctime来实现:

    find "${1}" -depth -mindepth 1 -maxdepth 1 -ignore_readdir_race -type f -cmin "+${2}" -delete
    

    这里一个存疑的问题就是:如果session_start之后没有修改过$_SESSION变量,那么Session文件是否会被更新?

    Session 的有效期是多久

    根据上面的描述,Session在server端的周期取决于session.gc_maxlifetime值。这个值的默认值可能是24分钟。

    Session的本质是server和client之间验证口令的一种方法,因此除了服务器端的考虑,还有客户端的考虑。

    客户端大多是以Cookie的形式维持这个Session,因此,对于客户端来说,主要是这个特殊的Session Cookie的有效期。

    在PHP中,即session.cookie_lifetime的值。这个值默认是0,即直到浏览器关闭为止。

    理论上,可以通过调整匹配session.gc_maxlifetimesession.cookie_lifetime的值让Session在浏览器关闭重启后继续保持。

    通常情况下,Session有效期的长短则显然主要取决于session.gc_maxlifetime的值,这个值默认是24分钟。

    TODO

    标签:

      分享到:
      comments powered by Disqus

      29/32ms