深入讲解PHP Session及如何保持其不过期的方法

SESSION的实现中采用COOKIE技术,SESSION会在客户端保存一个包含session_id(SESSION编号)的COOKIE;在服务器端保存其他session变量,比如session_name等等。当用户请求服务器时也把session_id一起发送到服务器,通过 session_id提取所保存在服务器端的变量,就能识别用户是谁了。同时也不难理解为什么SESSION有时会失效了。

当客户端禁用COOKIE时(点击IE中的“工具”—“Internet选项”,在弹出的对话框里点击“安全”—“自定义级别”项,将“允许每个对话COOKIE”设为禁用),session_id将无法传递,此时 SESSION失效。不过php5在linux/unix平台可以自动检查cookie状态,如果客户端设置了禁用,则系统自动把session_id附加到url上传递。windows主机则无此功能。

Session常见函数及用法?
Session_start() :开始一个会话或者返回已经存在的会话。
说明:这个函数没有参数,且返回值均为true。如果你使用基于cookie的session(cookie-based sessions),那么在使用Session_start()之前浏览器不能有任何输出,否则会发生以下错误:
Warning: Cannot send session cache limiter - headers already sent (output started at /usr/local/apache/htdocs/cga/member/1.php:2)…………

你可以在php.ini里启动session.auto_start=1,这样就无需每次使用session之前都要调用session_start()。但启用该选项也有一些限制,如果确实启用了 session.auto_start,则不能将对象放入会话中,因为类定义必须在启动会话之前加载以在会话中重建对象。
请求结束后所有注册的变量都会被序列化。已注册但未定义的变量被标记为未定义。在之后的访问中这些变量也未被会话模块定义,除非用户以后定义它们。

警告: 有些类型的数据不能被序列化因此也就不能保存在会话中。包括 resource 变量或者有循环引用的对象(即某对象将一个指向自己的引用传递给另一个对象)。

注册SESSION变量 :
PHP5使用$_SESSION[‘xxx']=xxx注册SESSION全局变量。和GET,POST,COOKIE的使用方法相似。
注意:session_register(),session_unregister ,session_is_registered在php5下不再使用,除非在php.ini里把register_globle设为on,不过出于安全考虑,强烈建议关闭register_globle。HTTP_SESSION_VARS也不提倡使用了,官方建议用$_SESSION代替之。例如:

Page1.php

  <?php
  Session_start(); //使用SESSION前必须调用该函数。

  $_SESSION[‘name']=”我是黑旋风李逵!”; //注册一个SESSION变量

  $_SESSION[‘passwd']=”mynameislikui”;
  $_SESSION[‘time']=time();
  echo '
  通过COOKIE传递SESSION'; //如果客户端支持cookie,可通过该链接传递session到下一页。

  echo '
  . SID . '">通过URL传递SESSION';//客户端不支持cookie时,使用该办法传递session.

  ?>

Page2.php

  <?php
  session_start();
  echo $_SESSION['name']; //

  echo $_SESSION['passwd']; //

  echo date('Y m d H:i:s', $_SESSION['time']);
  echo '
  返回山一页';
  ?>

有两种方法传递一个会话 ID:

  1. cookie
  2. URL 参数

会话模块支持这两种方法。cookie 更优化,但由于不总是可用,也提供替代的方法。第二种方法直接将会话 ID 嵌入到 URL 中间去。

PHP 可以透明地转换连接。除非是使用 PHP 4.2 或更新版本,需要手工在编译 PHP 时激活。在 Unix 下,用 --enable-trans-sid 配置选项。如果此配置选项和运行时选项 session.use_trans_sid 都被激活(修改php.ini),相对 URI 将被自动修改为包含会话 ID。

session_id
session_id() 用于设定或取得当前session_id。php5中既可以使用session_id(),也可以通过附加在url上的SID取得当前会话的session_id和session_name。
如果session_id()有具体指定值的话,将取代当前的session_id值。使用该函数前必须启动会话:session_start();
当我们使用session cookies时,如果指定了一个session_id()值,每次启动session_start()都会往客户端发送一个cookie值。不论当前session_id是否与指定值相等。
session_id()如果没有指定值,则返回当前session_id();当前会话没有启动的话,则返回空字符串。

检查session是否存在?
在以往的php版本中通常使用session_is_register()检查session是否存在,如果您使用$_SESSION[‘XXX']=XXX来注册会话变量,则session_is_register()函数不再起作用。你可以使用
isset($_SESSION[‘xxx'])来替代。

更改session_id session_regenerate_id() 更改成功则返回true,失败则返回false。
使用该函数可以为当前session更改session_id,但不改变当前session的其他信息。例如:

  <?php
  session_start();
  $old_sessionid = session_id();
  session_regenerate_id();
  $new_sessionid = session_id();
  echo "原始 SessionID: $old_sessionid
  ";
  echo "新的 SessionID: $new_sessionid
  ";
  echo"

  ";

  print_r($_SESSION);
  echo"";
  ?>

session_name() 返回当前session的name或改变当前session的name。如果要改变当前session的name,必须在session_start() 之前调用该函数。注意:session_name不能只由数字组成,它至少包含一个字母。否则会在每时每刻都生成一个新的session id.
session改名示例:

$previous_name = session_name("WebsiteID");
echo "新的session名为: $previous_name
";
?>

如何删除session?
1、unset ($_SESSION['xxx']) 删除单个session,unset($_SESSION['xxx']) 用来unregister一个已注册的session变量。其作用和session_unregister()相同。 session_unregister()在PHP5中不再使用,可将之打入冷宫。
unset($_SESSION) 此函数千万不可使用,它会将全局变量$_SESSION销毁,而且还没有可行的办法将其恢复。用户也不再可以注册$_SESSION变量。
2、$_SESSION=array() 删除多个session
3、 session_destroy()结束当前的会话,并清空会话中的所有资源。。该函数不会unset(释放)和当前session相关的全局变量 (globalvariables),也不会删除客户端的session cookie.PHP默认的session是基于cookie的,如果要删除cookie的话,必须借助setcookie()函数。
返回值:布尔值。
功能说明:这个函数结束当前的session,此函数没有参数,且返回值均为true

session_unset() 如果使用了$_SESSION,则该函数不再起作用。由于PHP5必定要使用$_SESSION,所以此函数可以打入冷宫了。

下面是PHP官方关于删除session的案例:

  <?php
  // 初始化session.

  session_start();
  /*** 删除所有的session变量..也可用unset($_SESSION[xxx])逐个删除。****/
  $_SESSION = array();
  /***删除sessin id.由于session默认是基于cookie的,所以使用setcookie删除包含session id的cookie.***/
  if (isset($_COOKIE[session_name()])) {
  setcookie(session_name(), '', time()-42000, '/');
  }

// 最后彻底销毁session.

  session_destroy();
  ?>

由此我们可以得出删除Session的步骤:

  1. session_start()
  2. $_SESSION=array()/unset($_SESSION['xxx'])
  3. session_destroy()

解决PHP Session不过期以及SessionId保持不变的问题

session 回收机制:
 
PHP采用Garbage Collection process对过期session进行回收,然而并不是每次session建立时,都能够唤起 ‘garbage collection' process ,gc是按照一定概率启动的。这主要是出于对服务器性能方面的考虑,每个session都触发gc,浏览量大的话,服务器吃不消,然而按照一定概率开启gc,当流览量大的时候,session过期机制能够正常运行,而且服务器效率得到节省。细节应该都是多年的经验积累得出的。
 
三个与PHP session过期相关的参数(php.ini中):

  1. session.gc_probability = 1
  2. session.gc_divisor = 1000
  3. session.gc_maxlifetime = 1440

gc启动概率 = gc_probability / gc_divisor = 0.1%
 
session过期时间 gc_maxlifetime 单位:秒
 
当web服务正式提供时,session过期概率就需要根据web服务的浏览量和服务器的性能来综合考虑session过期概率。为每个session都开启gc,显然是不明智的,感觉有点“碰运气”的感觉,要是访问量小命中几率就小。我在本机测试过程中,几乎都没有被命中过,sessionid几天都不变,哪怕机器重启。测试过程中,这个过期概率值要设置大一点命中几率才高点。
 
通过修改php配置文件的过期概率值,可以“碰运气”式的设置session过期,那有没有更好的办法呢?

下面写的这个session类可以彻底解决session不过期以及sessionid不变的问题。

<?php
 /**
 * 扩展Session类(简单封装)
 *
 * @author slimboy
 *
 */
class Session { 

   /**
   * 初始化
   */
  static function _init(){
    ini_set('session.auto_start', 0);
    //Session::start();
   } 

   /**
   * 启动Session
   */
  static function start() {
    session_start();
  } 

   /**
   * 设置Session
   *
   * @param $name Session名称
   * @param $value 值
   * @param $time 超时时间(秒)
   */
  public static function set($name,$value,$time){
    if(empty($time)){
      $time = 1800; //默认值
     }
    $_SESSION[$name] = $value;
    $_SESSION[$name.'_Expires'] = time() + $time;
  } 

   /**
   * 获取Session值
   *
   * @param $name Session名称
   */
  public static function get($name){
    //检查Session是否已过期
     if(isset($_SESSION[$name.'_Expires']) && $_SESSION[$name.'_E
 xpires']>time()){
      return $_SESSION[$name];
    }else{
      Session::clear($name);
      return null;
    }
  } 

   /**
   * 设置Session Domain
   *
   * @param $sessionDomain 域
   * @return string
   */
  static function setDomain($sessionDomain = null) {
    $return = ini_get('session.cookie_domain');
    if(!empty($sessionDomain)) {
      ini_set('session.cookie_domain', $sessionDomain);//跨
 域访问Session
     }
    return $return;
  } 

   /**
   * 清除某一Session值
   *
   * @param $name Session名称
   */
  static function clear($name){
    unset($_SESSION[$name]);
    unset($_SESSION[$name.'_Expires']);
  } 

   /**
   * 重置销毁Session
   */
  static function destroy(){
    unset($_SESSION);
    session_destroy();
  } 

   /**
   * 获取或设置Session id
   */
  static function sessionid($id=null){
    return session_id($id);
  } 

}
?>
简单调用:

<?php
  //设置session
  Session::set('UserId', $userid, 3600);
  //读取session
  $userId = Session::get('UserId');
?>
(0)

相关推荐

  • PHP中怎样保持SESSION不过期 原理及方案介绍

    PHP中如何保持SESSION以及由此引发的一些思考  最近的一个项目,里面有一个比较大的表单,用户完成它需要很多时间,很多用户花了千辛万苦完成之后,一提交发现SESSION过期,系统退出了,所以引起了研究如何设置SESSION以及保持SESSION在线的需要,下面是一些心得体会. 什么是SESSION?按照WIKI的解释,SESSION是存在于两个通信设备间的交互信息,在某一时间建立,经过一定的时间后失效.常见的SESSION有:TCP SESSION.WEB SESSION(HTTP SES

  • 详解php设置session(过期、失效、有效期)

    在php中设置session有很多方面包有给session设置值或直接设置过期.失效和有效期,下面小编来给大家给各位朋友介绍怎么使用. 我们先来看看在php.ini中session怎么设置,打开 php.ini,查找Session设置部分中以下一项,代码如下: session.save_path = "N;/path" session.save_path = "C:/Temp" #此处以你自己设定的路径为准 这项设置提供给我们可以给session存放目录进行多级散列

  • 解析PHP的session过期设置

    网上很多人给出了解答:修改php配置文件中的session.gc_maxlifetime.如果想了解更多session回收机制,继续阅读.(本文环境php5.2) 概述:每一次php请求,会有1/100的概率(默认值)触发"session回收".如果"session回收"发生,那就会检查/tmp/sess_*的文件,如果最后的修改时间到现在超过了1440秒(gc_maxlifetime的值),就将其删除,意味着这些session过期失效. 1. session在se

  • php 如何设置一个严格控制过期时间的session

    1.php session 有效期 PHP的session有效期默认是1440秒(24分钟),如果客户端超过24分钟没有刷新,当前session会被回收,失效. 当用户关闭浏览器,会话结束,session也会失效. 可以修改php.ini的session.gc_maxlifetime来设置session的生命周期,但并不能保证在超过这一时间后session信息立即会删除.因为GC是按机率启动的,可能在某一个长时间内都没有被启动.那么大量的session在超过session.gc_maxlifet

  • php中实现精确设置session过期时间的方法

    大多数据情况下我们对于session过期时间使用的是默认设置的时间,而对于一些有特殊要求的情况下我们可以设置一下session过期时间. 对此,可以在PHP中,设置php.ini,找到session.gc_maxlifetime = 1440 #(PHP5默认24分钟) 这里你可以随便设置一下过期时间.但是有人说设置以后,好象不起作用! 其实不是不起作用,而是因为系统默认: session.gc_probability = 1 session.gc_divisor = 1000 garbage

  • php中session过期时间设置及session回收机制介绍

    网上很多人给出了解答:修改配置文件中的session.gc_maxlifetime.如果想了解更多session回收机制,继续阅读.(本文环境php5.2) 概述:每一次php请求,会有1/100的概率(默认值)触发"session回收".如果"session回收"发生,那就会检查/tmp/sess_*的文件,如果最后的修改时间到现在超过了1440秒(gc_maxlifetime的值),就将其删除,意味着这些session过期失效. 1. session在端(一般是

  • PHP中的session永不过期的解决思路及实现方法分享

    我们前期开发了一个只有公司客服人员才能使用的系统--有限的几个客服人员.就是这有限的几个客服人员前几天突然就提出这样的问题:我们每隔很短一段时间 (半个小时不操作页面),正着急解决客户问题的时候,系统却提示需要登录,耽误了客户的时间-- 这很不爽! 客户就是上帝,唯一的上帝.于是上峰要求我们能够实现PHP中的session永不过期,除非我们的客服人员人为的让他过期了.出于安全性的考虑我很不理解这种永不过期的行为;出于懒惰的原因我真的不想修改以前的程序.但是没有办法,我依然需要改. 不修改程序是最

  • PHP中设置一个严格30分钟过期Session面试题的4种答案

    今天在我的微博上发出一个问题: 我在面试的时候, 经常会问一个问题: "如何设置一个30分钟过期的Session?", 大家不要觉得看似简单, 这里面包含的知识挺多, 特别适合考察基本功是否扎实, 谁来回答试试? 呵呵 为什么问这个问题呢? 1.我在stackoverflow上看到了有人讨论这个问题 2.想起来我经常问这个问题, 所以~~ 在这里, 我来解答下这个题目. 第一种回答 那么, 最常见的一种回答是: 设置Session的过期时间, 也就是session.gc_maxlife

  • 深入讲解PHP Session及如何保持其不过期的方法

    SESSION的实现中采用COOKIE技术,SESSION会在客户端保存一个包含session_id(SESSION编号)的COOKIE:在服务器端保存其他session变量,比如session_name等等.当用户请求服务器时也把session_id一起发送到服务器,通过 session_id提取所保存在服务器端的变量,就能识别用户是谁了.同时也不难理解为什么SESSION有时会失效了. 当客户端禁用COOKIE时(点击IE中的"工具"-"Internet选项",

  • PHP基于cookie与session统计网站访问量并输出显示的方法

    本文实例讲述了PHP基于cookie与session统计网站访问量并输出显示的方法.分享给大家供大家参考,具体如下: <?php $f_open = fopen("count.txt","r+"); //打开指定的文件 $count = fgets($f_open); //读取文件中的数据 if(empty($_COOKIE['cookie_name'])){ //判断COOKIE的是否存在 setcookie("cookie_name",

  • web服务器集群(多台web服务器)session同步、共享的3种解决方法

    在做了web集群后,你肯定会首先考虑session同步问题,因为通过负载均衡后,同一个IP访问同一个页面会被分配到不同的服务器上,如果session不同步的话,一个登录用户,一会是登录状态,一会又不是登录状态.所以本文就根据这种情况给出三种不同的方法来解决这个问题: 一.利用数据库同步session 在做多服务器session同步时我没有用这种方法,如果非要用这种方法的话,我想过二种方法: 1,用一个低端电脑建个数据库专门存放web服务器的session,或者,把这个专门的数据库建在文件服务器上

  • PHP+Session防止表单重复提交的解决方法

     index.php 当前表单页面is_submit设为0 SESSION_START(); $_SESSION['is_submit'] = 0; <form id="reg" action="post.php" method="post"> <p>用户名:<input type="text" class="input" name="username" i

  • Java 图文并茂讲解两种找二叉树的最近公共祖先的方法

    目录 思路一:先假设这棵树是二叉搜索树 思路二:假设该树是用孩子双亲表示法 思路一:先假设这棵树是二叉搜索树 首先我们补充说明一下什么是二叉搜索树: 在二叉搜索树中,对于每一个节点来说,他的左子树中的值都比他小,右子树的中的值都比他大.所以二叉搜索树的中序遍历是一组有序的数据. 对于上述这棵树,假设要求 p q 的最近公共祖先. 那么它有以下情况: 对于普通的二叉树来说,也无非就这几种情况:pq都在左,pq都在右,pq一左一右,pq有一个是根节点. 所以分别递归的去左子树和右子树中找 p q 节

  • Java 讲解两种找二叉树的最近公共祖先的方法

    目录 思路一:先假设这棵树是二叉搜索树 思路二:假设该树是用孩子双亲表示法 思路一:先假设这棵树是二叉搜索树 首先我们补充说明一下什么是二叉搜索树: 在二叉搜索树中,对于每一个节点来说,他的左子树中的值都比他小,右子树的中的值都比他大.所以二叉搜索树的中序遍历是一组有序的数据. 对于上述这棵树,假设要求 p q 的最近公共祖先. 那么它有以下情况: 对于普通的二叉树来说,也无非就这几种情况:pq都在左,pq都在右,pq一左一右,pq有一个是根节点. 所以分别递归的去左子树和右子树中找 p q 节

  • JS字符串分割方法整理汇总示例讲解(3种截取方法和6个辅助方法)

    目录 一.使用 slice() 截取 1,函数说明 2,使用样例 二.使用 substring() 截取 1.函数说明 2.使用样例 三.使用 substr() 截取 1.函数说明 2.使用样例 附:其他一些常用的方法 1.indexOf() 2,lastIndexOf() 3,split() 4,join() 5,concat() 6,charAt() JavaScript在开发中常常会需要截取字符串,而JS提供了slice() .substring().substr() 3种方法实现截取操作

  • asp中设置session过期时间方法总结

    如果程序中没有设置session的过期时间,那么session过期时间就会按照IIS设置的过期时间来执行,IIS中session默认过期时间为20分钟,IIS中session时间可以更改 时间设置要放在前面 例如 复制代码 代码如下: Session.Timeout=30 'SEESION有效时间为30分钟 Session("ID")=Rs("id") Session("Name")=Rs("Name") Session(&q

  • Java中设置session超时(失效)的三种方法

    1.在web容器中设置(此处以tomcat为例) 在tomcat-5.0.28\conf\web.xml中设置,以下是tomcat 5.0中的默认配置: 复制代码 代码如下: <!-- ==================== Default Session Configuration ================= -->    <!-- You can set the default session timeout (in minutes) for all newly   --&

  • ThinkPHP的cookie和session冲突造成Cookie不能使用的解决方法

    近期做一个网站的投票时,遇到ThinkPHP中的cookie和session冲突导致Cookie不能使用的情况. 该网站采用的是ThinkPHP框架制作,有一页面上面展示很多图片,要求每个图片下面有对应的投票,通过限制ip地址来,限制游客在一定时间范围内,能对多个图片投票,但是每个图片只能投票一次,开始使用ip存储在数据库解决,后来改进为使用session存储,ip在服务文件里,不过要把生成的sessionid存储在本地的cookie中,按照ThinkPHP手册说明操作session一切顺利,但

随机推荐