什么情况下会调用到session_destroy()

时间:2022-08-02 03:39:33

https://segmentfault.com/q/1010000000191102

首先 ... session_destory() 是一个函数 ...

这个函数在任何情况下都不会被 php 引擎自动调用 ... 只能你手工去调用 ...

php 内部存在着清理 session 的机制 ... 但与这个函数完全无关 ...

如果你想问的是什么时候该手工调用这个函数 ...答案就是在你想完全清理掉当前 session 的时候 ...

问题里面提及的几种情况 ... 不管是关闭网页也好 ... 关闭浏览器也罢 ... 甚至你把浏览器删掉重装了 ...

都不会影响到已经生成的 session ... 一言以蔽之 ... 所有浏览器行为都不会导致 session 被自动销毁 ...

那么 ... php 到底是如何清理 session 的呢 ..?

仔细去读 php.ini ... 你可以发现如下几行 ...

; Defines the probability that the 'garbage collection' process is started
; on every session initialization. The probability is calculated by using
; gc_probability/gc_divisor. Where session.gc_probability is the numerator
; and gc_divisor is the denominator in the equation. Setting this value to 1
; when the session.gc_divisor value is 100 will give you approximately a 1%
; chance the gc will run on any give request.
; Default Value: 1
; Development Value: 1
; Production Value: 1
; http://php.net/session.gc-probability
session.gc_probability = 1 ; Defines the probability that the 'garbage collection' process is started
; on every session initialization. The probability is calculated by using
; the following equation: gc_probability/gc_divisor. Where session.gc_probability
; is the numerator and session.gc_divisor is the denominator in the equation.
; Setting this value to 1 when the session.gc_divisor value is 100 will give you
; approximately a 1% chance the gc will run on any give request. Increasing this
; value to 1000 will give you a 0.1% chance the gc will run on any give request.
; For high volume production servers, this is a more efficient approach.
; Default Value: 100
; Development Value: 1000
; Production Value: 1000
; http://php.net/session.gc-divisor
session.gc_divisor = 1000 ; After this number of seconds, stored data will be seen as 'garbage' and
; cleaned up by the garbage collection process.
; http://php.net/session.gc-maxlifetime
session.gc_maxlifetime = 1440

其实英文的注释已经说得很明白了 ... 但如果你不想看 ... 我也可以解释给你听 ...

由于 php 的工作机制 ... 它本身不会提供 daemon 来定时扫描 session 信息并判断其是否失效 ...

当你每次调用 session_start() 时 ...

php 会根据 session.gc_probability 和 session.gc_divisor 来决定是否启用 Garbage Collector ...

Garbage Collector 顾名思义 ... 被叫做 垃圾回收器 ... 也就是俗称的 GC ...

具体一些讲 ... 在我刚刚贴的配置文件里 ...

session.gc_probability = 1
session.gc_divisor = 1000

就是说 php 会有千分之一的概率会启动垃圾回收 ...

而垃圾回收的工作就是在 session 存储路径 session.save_path 下扫描所有存在的 session ...

然后用当前时间减去每个 session 的最后修改时间再跟 session.gc_maxlifetime 参数进行比较 ...

如果某个 session 的生存时间超过了 session.gc_maxlifetime 的设定值就把它销毁掉 ...

事实上这个过程完全是 php 引擎的行为 ... 和你的程序无关 ... 和用户做了什么也无关 ...

用户关闭浏览器再开 ... 因为 cookie 失效他会获得一个新的 session ...

但这并不代表他原来的 session 就被销毁了 ... 那个 session 依然在服务器上存在 ...

如果他手动把名字等于 session.name 的那个 cookie 的值改回之前的 session_id() ...

还是可以重新获得之前的那个 session 的 ...

另外一种情况 ... 如果一个用户获得 session 之后长时间没有任何动作 ...

他就可能因为其他用户触发了垃圾回收而丢失掉自己的 session ...

大体来说就是如此 ... 更加细节的东西 ... 你可以参考 php 手册上 关于垃圾回收的章节 ...

恩 ... 就是这样啦 ...

//-------------------------------------------------------------------------------

深入理解session过期机制

首先得明白:session的过期时间由两方面决定的; 
1存储在客户端的$_COOKIE['PHPSESSID']的过期时间(默认cookie名称为PHPSESSID,可通过php.ini中的session.name修改。) 
2.存储在服务器端的相对应的session文件(session文件名和上述cookie的值一一对应),默认为1440秒,即24分钟

ok,现在详细阐述上述两者的关系: 当执行session_start()的时候,其实是做了两件事: 1,检查客户端发送过来的的所有cookie(当然也包括$_COOKIE['PHPSESSID'], 如果有的话),根据$_COOKIE['PHPSESSID']的值(这是由apache产生的随机字符串,如0lkbd2se458r600m2m7o1r4ic5)来访问 相对应的 session文件(如:sess_0lkbd2se458r600m2m7o1r4ic5,我的默认存储在‘E:\wamp\tmp’下),这两者是一 一对应的关系。打个比喻:$_COOKIE['PHPSESSID']就是一把开启宝盒的钥匙,而那个宝盒就是session文件,里面存储着用户的重要 信息,也就是session的值, 如:$_SESSION['uid']=1,$_SESSION['username']='name',$_SESSION['pwd']='pwd', 当然文件里面的值是经过序列化的。 2,如果客户端没有传来$_COOKIE['PHPSESSID'],就会有服务端产生一个随机的$_COOKIE['PHPSESSID']并存储在客户端。

明白上面这些,我们可以通过下面的方法修改session的过期时间: 
1.session_set_cookie_params('50');//修改$_COOKIE['PHPSESSID'],的生存时间为50秒

(或者可以这样: setcookie(session_name(),session_id(),time()+50);)

2.ini_set('session.gc_maxlifetime','50');//设置session文件的有效时间为50秒

但是,可能有些朋友会做这样 一个试验, 在50秒内获取$_COOKIE['PHPSESSID']的值并记录下来(如黑客截获这个cookie),这样等50秒过后发现原先 的$_COOKIE['PHPSESSID']值确实不存在了,而出现了一个新的$_COOKIE['PHPSESSID'],但是‘E:\wamp \tmp’下的旧session文件却没有消失(默认只有1/1000的概率会消失,应该不会碰到吧,呵呵),这是为什么呢?我不是已经设置了.ini_set('session.gc_maxlifetime','50');了 吗?再做一个实验:这时你伪造一个$_COOKIE['PHPSESSID'],值为刚才你记录下的,神奇的事发生了,你依然可以访问刚才旧的 session文件!!!(虽然他已经过期),只要这个文件没被删除,用相对应得$_COOKIE['PHPSESSID']依然可以进行访问!!!

那我们设置ini_set('session.gc_maxlifetime', '50');还有什么意义呢?这就涉及的GC(GarbageCollector)的回收机制。 
默 认情况下,session.gc_probability = 1,session.gc_divisor=1000,也就是说有1/1000的可能性会启动GC。GC的工作,就是扫描所有的session信息,用当 前时间减去session的最后修改时间(modifieddate),同session.gc_maxlifetime参数进行比较,如果生存时间已经 超过gc_maxlifetime,就把该session删除。只要没有启动GC,即使session过期,也仍旧可通过相对应 得$_COOKIE['PHPSESSID']进行访问! 
   
原文参考: http://www.jb51.net/article/26890.htm 
                 http://www.php100.com/html/webkaifa/PHP/PHPyingyong/2012/0621/10583.html

什么情况下会调用到session_destroy()的更多相关文章

  1. C++11 std::call_once:保证函数在任何情况下只调用一次

    std::call_once的作用是很简单的, 就是保证函数或者一些代码段在并发或者多线程的情况下,始终只会被执行一次.比如一些init函数,多次调用可能导致各种奇怪问题. 给个例子: #includ ...

  2. layoutSubviews在什么情况下会被调用

    layoutSubviews在以下情况下会被调用: 1.init初始化不会触发layoutSubviews. 2.addSubview会触发layoutSubviews. 3.设置view的Frame ...

  3. 数据库表设计时一对一关系存在的必要性 数据库一对一、一对多、多对多设计 面试逻辑题3.31 sql server 查询某个表被哪些存储过程调用 DataTable根据字段去重 .Net Core Cors中间件解析 分析MySQL中哪些情况下数据库索引会失效

    数据库表设计时一对一关系存在的必要性 2017年07月24日 10:01:07 阅读数:694 在表设计过程中,我无意中觉得一对一关系觉得好没道理,直接放到一张表中不就可以了吗?真是说,网上信息什么都 ...

  4. c++中六种构造函数的实现以及9中情况下,构造函数的调用过程

    六种构造函数的实现代码例如以下: #include<iostream> using namespace std; //c++中六种默认的构造函数 class Test { public: ...

  5. RPC 框架要实现这个功能,我们可以使用泛化调用。那什么是泛化调用呢?我们带着这个问题,先学习下如何在没有接口的情况下进行 RPC 调用。

    RPC 框架要实现这个功能,我们可以使用泛化调用.那什么是泛化调用呢?我们带着这个问题,先学习下如何在没有接口的情况下进行 RPC 调用.

  6. 关于JDBC技术中,调用MySQL中不建议在没有服务器身份验证的情况下建立SSL连接错误解决

    今天学习到了JBDC前沿:对JDBC编写步骤的封装,出现了一大串红色报错(当然,也不能叫报错,毕竟不是所有的红色都是错误eeror,) 错误如下: Establishing SSL connectio ...

  7. c&num; &period;netframwork 4&period;0 调用 2&period;0时报错 混合模式程序集是针对&OpenCurlyDoubleQuote;v2&period;0&period;50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4&period;0 运行时中加载该程序集。

    “System.IO.FileLoadException”类型的未经处理的异常在 XXX.dll 中发生 其他信息: 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的 ...

  8. PHP通过加锁实现并发情况下抢码实现

    需求:抢码功能 要求: 1.特定时间段才开放抢码: 2.每个时间段放开的码是有限的: 3.每个码不允许重复: 实现: 1.在不考虑并发的情况下实现: function get_code($len){ ...

  9. 什么情况下才要重写Objective-C中的description方法

    特别注意: 千万不要在description方法中同时使用%@和self,同时使用了%@和self,代表要调用self的description方法,因此最终会导致程序陷入死循环,循环调用descrip ...

随机推荐

  1. k近邻&lpar;KNN&rpar;复习总结

    摘要: 1.算法概述 2.算法推导 3.算法特性及优缺点 4.注意事项 5.实现和具体例子 6.适用场合内容: 1.算法概述 K近邻算法是一种基本分类和回归方法:分类时,根据其K个最近邻的训练实例的类 ...

  2. JAVA操作Mysql数据库

    String driver = "com.mysql.jdbc.Driver"; String url = "jdbc:mysql://127.0.0.1:3306/ph ...

  3. diff和common

    diff 命令 diff命令:找出两个文件的不同点,用于比较文件的差异 linux上非常重要的工具,一般用于制作补丁文件,特别是比较两个版本不同的文件以找到改动的地方. diff在命令行中打印每一个行 ...

  4. 一张图看Goodle Clean设计架构

    之前用一张图分析了Google给出的MVP架构,但是在Google给出的所有案例里面除了基本的MVP架构还有其它几种架构,今天就来分析其中的Clean架构.同样的,网上介绍Clean架构的文章很多,我 ...

  5. 11g RAC R2 体系结构---进程,日志

    进程结构:Overview of Oracle Clusterware Platform-Specific Software Components When Oracle Clusterware is ...

  6. jekyll themes

    jekyll主题下载: https://mademistakes.com/work/jekyll-themes/ https://github.com/jekyll/jekyll/wiki/Theme ...

  7. 直接拿来用的15个jQuery代码片段

    1.预加载图片 1 2 3 4 5 6 7 8 9 10 11 12 (function($) {   var cache = [];   // Arguments are image paths r ...

  8. CoreLocation&plus;MapKit系统定位&lpar;含坐标以及详细地址&rpar;

    iOS8 之后出现一些新的配置 [self.manager requestWhenInUseAuthorization]; 并且在info.plist文件中增加 NSLocationWhenInUse ...

  9. Linux MTD子系统 &lowbar;从模型分析到Flash驱动模板

    MTD(Memory Technology Device)即常说的Flash等使用存储芯片的存储设备,MTD子系统对应的是块设备驱动框架中的设备驱动层,可以说,MTD就是针对Flash设备设计的标准化 ...

  10. 记一次令人窒息的线上fullgc调优

    今天第二篇采坑了... ... 现场因为处理太急促没有保留,而且是一旁协助,没有收集到所有信息实在是有些遗憾...只能靠记忆回想一些细节 情况是一台服务器一启动就开始full gc,短短1分钟可以有几 ...