zoukankan      html  css  js  c++  java
  • php 会话控制(关于session的维护与生命周期)

        Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器创建生成一个唯一的sessionID,用该sessionID为标识符存取服务器端的Session存储空间,在会话期间,分配给客户端的唯一sessionID,用来标识当前用户,与其他用户进行区分。

        sessionID也可以作为会话信息保存到数据库中,进行session持久化。这样可以跟踪用户的登陆次数、在线与否在线时间等从而维护HTTP无状态事物之间的关系。session的内容存储键值对的列表,键是字符串类型,session的存储更方便,值可以是对象。

        在session会话期间,session会分别保存在客户端和服务器端两个文件,客户端可以是cookie方式保存的sessionID(默认的保存方式)或通过url字符串形式传递。服务器端一般以文本的形式保存在指定的session目录中。在服务器端session.use_cookies来控制客户端使用哪一种保存方式。

        如果定义为cookie保存方式,我们可以通过session.cookie_lifetime(默认值0,闭浏览器就清除)来控制被保存在client上的cookie的有效期

        而如果客户端用cookie方式保存的sessionID,则使用“临时”的cookie保存(cookie的名称为PHPSESSID,通过Firebug你可以了解到详细的信息,该名称你可以通过php.ini session.name进行更改),用户提交页面时,会将这一SessionID提交到服务器端,来存取session数据。这一过程,是不用开发人员干预的

    Session的创建

        session_start()

        功能:

          初始化Session,也标识着session生命周期的开始。要使用session,必须初始化一个session环境,有点类似于OOP概念中调用构造函数构创建对象实例一样。session初始化操作,声明一个全局数组$_SESSION,映射寄存在内存的session数据。如果session文件已经存在,并且保存有session数据,session_start()则会读取session数据,填入$_SESSION中,开始一个新的session生命周期。

        说明:

          如果在php.ini中session.auto_start=1开启,则在每个页面执行session_start(),不需要手工设置,该选项默认为关闭状态,开启后不能将对象放入session中。

        Session ID

          用户session唯一标识符,随机生成的一串字符串,具有唯一性,随机性。主要用于区分其它用户的session数据。用户第一次访问web页面的时候,php的session初始化函数调用会分配给当前来访用户一个唯一的ID,也称之为session_id。

        获得session_id():

          echo $_COOKIE['PHPSESSID'].'<br/>';
          echo $_COOKIE[session_name()].'<br/>';
          echo session_id().'<br/>';

    备注

        php默认的session是基于cookie的,如果要删除cookie的话,必须借助setcookie()函数

        session_unset()和unset()函数区别:

          在session生命周期,session_unset()从当前session中注销全部session数据,让$_SESSION成为一个空数组。它与unset($_SESSION)的区别在于:unset直接删除$_SESSION变量,释放内存资源;另一个区别在于,session_unset()仅在session生命周期能够操作$_SESSION数组,而unset()则在整个页面(page)生命周期都能操作$_SESSION数组。session_unset()同样不进行任何IO操作,只影响$_SESSION数组。

    Session生命周期(session lifetime):Session失效时间与过期回收机制

        我们把初始化session开始,直到注销session这段期间,称为session生命周期。默认的,php会将session保存在php.ini配置中session.save_path设定的目录下

        设置SESSION的生命周期

          php session是基于cookie的,所以要设置session的生命周期,首先要设置cookie的失效时间。因为在客户端(如浏览器)登录网站时,SESSION 是否有用,首先找客户端是否有 COOKIE,通过COOKIE 中的 SESSION ID 去找服务器上的文件

        其实PHP5 Session还提供了一个函数 session_set_cookie_params(); 来设置PHP5 Session的生存期的,该函数必须在 session_start() 函数调用之前调用

        在服务器端,php如何判断session文件是否过期?

          session.gc_maxlifetime = 1440 (初始值)#设置session存活时间,单位是秒。每次GC启动后, 会通过stat得到session文件最后访问的unix时间,通过现在时间减去文件最后访问时间之间大于session.gc_maxlifetime,则会删除该文件。

          如果"最后的修改时间"到"现在"超过了session.gc_maxlifetime(默认是1440)秒,也就是说在这里设置的时间内,该文件没有被修改过,这个session文件就被认为是过期了,由于php5的session采用被动的回收机制,过期的session文件不会自己消失,而是通过触发“回收”来处理过期的session,那么在下一次session回收的时候,如果这个文件仍然没有被更改过,这个session文件就会被删除(session就过期了)。

        session回收何时发生

          默认情况下,每一次php请求,就会有1%的概率发生回收,所以可能简单的理解为“每100次php请求就可能有一次回收概率发生”。这个概率是通过以下参数控制的:

            session.gc_probability = 1 (初始值)
            session.gc_divisor = 100 (初始值)

            #由这二个函数决定了启用GC的概率,默认是1/1000。也就是说,每一千次用户请求中有一次会启动GC回收session。启动GC进程不宜过于频繁。过于频繁访问的网站,并发量大的网站,可减小PHP GC的启动频率。PHP GC回收session会降低php的执行效率。

          这两个合起来就是启动Gabadge Collection(gc)进程管理概率的,在session初使化时(session_start())。Gabadge Collection启动后跟踪session信息文件。其启动概率为session.gc_probability/session.gc_divisor。也就是说不是每个session信息文件都有100%的被系统当作垃圾来处理的。如果直接关闭浏览器的话,session信息文件很多情况下都是留在了服务器上,如果把概率改成了100%,虽然Gabadge Collection百分之百被启动了,但是这会对服务器添加负荷,也就失去了GC本身的意义了。

          补充说明

            假设这种情况session.gc_maxlifetime=1440,如果某个session文件最后修改时间是1440秒之前,那么在下一次回收(1/100的概率)发生前,这个session仍然是有效的;

            如果你的session使用session.save_path中使用别的地方保存session,session回收机制有可能不会自动处理过期session文件。这时需要定时手动(或者crontab)的删除过期的session:cd /path/to/sessions; find -cmin +24 | xargs rm;

            注意,当服务器端session文件数量没有得到有效的回收,逐渐增长到GB或更大级别时可能你的站点在存取session时就会越来越缓慢,多见于站点登入登出会受到影响;

            写日志、周报、月报等时候我们最后提交的关头,有时会出现”无效的操作,请登陆后重试”等消息,其原因也不言而喻,可能就是session失效,gc清除那些已经“超时”的session文件。

            一些特殊情况:

              因为回收机制会检查文件的“最后修改时间”,所以如果某个会话是活跃的,但是session的内容没有改变过,那么对应的session文件也就没有改变过,回收机制会认为这是一个长时间没有活跃的session而将其删除。这是我们不愿看到的,可以通过增加如下的简单代码解决这个问题:

                <?php
                  if(!isset($_SESSION['last_access'])||(time()-$_SESSION['last_access'])>120)
                      $_SESSION['last_access'] = time(); 
                ?> 

  • 相关阅读:
    Python中所有的关键字
    关于selenium的8种元素定位
    对提示框的操作
    selenium+webservice进行百度登录
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled...报错解决
    Vue中使用echarts
    npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142解决方法
    插入排序
    冒泡排序优化
    roject 'org.springframework.boot:spring-boot-starter-parent:XXX' not found 解决
  • 原文地址:https://www.cnblogs.com/lijiageng/p/6900298.html
Copyright © 2011-2022 走看看