这里有新鲜出炉的 PHP 面向对象编程,程序狗速度看过来!
PHP(外文名: Hypertext Preprocessor,中文名:"超文本预处理器")是一种通用开源脚本语言。语法吸收了 C 语言、Java 和 Perl 的特点,入门门槛较低,易于学习,使用广泛,主要适用于 web 开发领域。PHP 的文件后缀名为 php。
Session 在开发中是非常重要的一个数据存储变量了,它可以实现不同页面之间的传值了,下面我们来为各位介绍在使用 Session 时碰到过期无效的一些问题吧, 需要的朋友可以参考下
php Session 无效分析
PHP 开发过程中,可能有朋友经常会遇到 Session 所产生的文件无法自动清除的问题,其实并非真的无法清除,而是有一个概率问题,只要你的站点访问量足够大,那些文件就可以自动被清除掉。如果访问量比较少,又看那些文件不顺眼的话,只要在 php.ini 里的配置一下即可实现 Session 文件自动清除的功能,具体配置如下:
找到
session.gc_probability = 1
session.gc_divisor = 1000
上面这两项参数其实就是这个概率,默认情况下是 1/1000
将 session.gc_divisor = 1000 改为 session.gc_divisor = 100 即可
如果想达到完全的实时,那么可以把这个参数改为 1,这样概率就是 100% 了
看看 session 如何工作的
概述:每一次 php 请求,会有 1/100 的概率(默认值)触发 "session 回收"。如果 "session 回收" 发生,那就会检查 / tmp/sess_* 的文件,如果最后的修改时间到现在超过了 1440 秒(gc_maxlifetime 的值),就将其删除,意味着这些 session 过期失效。
1. session 在 server 端(一般是 Apache with PHP module)如何存在的?
默认的,php 会将 session 保存在 / tmp 目录下,文件名为这个样子:sess_01aab840166fd1dc253e3b4a3f0b8381。每一个文件对应了一个 session(会话)。
- more / tmp / sess_01aab840166fd1dc253e3b4a3f0b8381 username | s: 9 : "jiangfeng";
- admin | s: 1 : "0〃;
#变量名 | 类型: 长度: 值
删除这里的 session 文件,就表示对应的 session 失效了。
2. session 在 client 端(一般是浏览器)如何存在的?
session 在浏览器端,只需要保存 session ID(由 server 端生成的唯一 ID)就可以了。有两种保存方式:在 cookie 中、在 url 里面。如果 cookie 中保存 session ID,就可以看到浏览器的 cookie 中有一个 PHPSESID 变量。如果是 URL 传递的,就可以看到形如:
index.php?PHPSESID=01aab840166fd1dc253e3b4a3f0b8381 的 URL。(在 server 端通过 session.use_cookies 来控制使用哪一种方式)
3. 在 server 端,php 如何判断 session 文件是否过期?
如果 "最后的修改时间" 到 "现在" 超过了 gc_maxlifetime(默认是 1440)秒,这个 session 文件就被认为是过期了,在下一次 session 回收的时候,如果这个文件仍然没有被更改过,这个 session 文件就会被删除(session 就过期了)。
简单的说,如果我登录到某网站,如果在 1440 秒(默认值)内没有操作过,那么对应的 session 就认为是过期了。
所以,修改 php.ini 文件中的 gc_maxlifetime 变量就可以延长 session 的过期时间了:(例如,我们把过期时间修改为 86400 秒)
session.gc_maxlifetime = 86400
然后,重启你的 web 服务(一般是 apache)就可以了。
注意:php5 里面 session 过期使用了回收机制。这里设置时间为 86400 秒,如果 session 在 86400 秒内没有被修改过,那么在下一次 "回收" 时才真的被删除。
4. session"回收" 何时发生?
默认情况下,每一次 php 请求,就会有 1/100 的概率发生回收,所以可能简单的理解为 "每 100 次 php 请求就有一次回收发生"。这个概率是通过以下参数控制的
#概率是 gc_probability/gc_divisor
session.gc_probability = 1
session.gc_divisor = 100
注意 1:假设这种情况 gc_maxlifetime=120,如果某个 session 文件最后修改时间是 120 秒之前,那么在下一次回收(1/100 的概率)发生前,这个 session 仍然是有效的。
注意 2:如果你的 session 使用 session.save_path 中使用别的地方保存 session,session 回收机制有可能不会自动处理过期 session 文件。这时需要定时手动(或者 crontab)的删除过期的 session:
cd /path/to/sessions; find -cmin +24 | xargs rm
5. 一些特殊情况
因为回收机制会检查文件的 "最后修改时间",所以如果某个会话是活跃的,但是 session 的内容没有改变过,那么对应的 session 文件也就没有改变过,回收机制会认为这是一个长时间没有活跃的 session 而将其删除。这是我们不愿看到的,可以通过增加如下的简单代码解决这个问题:
- <?php
- if(!isset($_SESSION['last_access'])||(time()-$_SESSION['last_access'])>60)
- $_SESSION['last_access'] = time();
- ?>
代码会每隔 60 秒,尝试修改修改一次 session。
总结:如果想修改 session 过期时间,修改变量 gc_maxlifetime 就可以了。php5 的 session 采用被动的回收机制(garbage collection)。过期的 session 文件不会自己消失,而是通过触发 "回收" 来处理过期的 session。
我们下面来详细看看一些其它的设置 session 时间的问题
Session 过期时间参数
设定过期时间参数, 主要是设定 session.gc_maxlifetime 的参数即可, 再保险一点的设定, 就设定下面这两个参数.
- ini_set('session.cookie_lifetime', 0); // 可用 print_r(session_get_cookie_params()); 观察
- ini_set('session.gc_maxlifetime', 3600); // 可用 echo ini_get("session.gc_maxlifetime"); 观察
session_cookie_lifetime 设为 0 的话, 代表等到 browser 才把此 cookie 清掉.(session 和 browser cookie 是有相关的)
如果懒得想这些, 直接用下面的 function 就可以了
Session 过期时间程式
- <?php
- function start_session($expire = 0)
- {
- if ($expire == 0) {
- $expire = ini_get('session.gc_maxlifetime');
- } else {
- ini_set('session.gc_maxlifetime', $expire);
- }
- if (empty($_COOKIE['PHPSESSID'])) {
- session_set_cookie_params($expire);
- session_start();
- } else {
- session_start();
- setcookie('PHPSESSID', session_id(), time() + $expire);
- }
- }
- ?>
使用方式
于程式最上方加入: start_session(600); // 代表 600 秒后会过期 (取代原本 session_start())
如果要再延长过期时间, 只要再做修改即可.
但是有个问题要注意, 就是 PHP 的 session 预设是存成 file, 所以 /tmp 可能会因这样设定而爆掉 (档案太多), 通常解法是把 session 存进 DB/memcache 中.
来源: http://www.phperz.com/article/17/0806/340996.html