session会话技术

session

理解:
  1. session会话数据的存储位置:服务器端。
  2. 实现方式:
    2.1 在 服务器端,建立很多的会话数据区(session数据区)
    2.2 为 每个session会话数据区分配唯一标识
    2.3 将该唯一标识,分配给对应会话浏览器(因此:session技术基于COOKIE技术!)
操作步骤:
1、开启session机制
session_start();//开启后,会生成一个独立的session_id,用于后期与该浏览器建立通信。
2、操作session数据
session_start();//开启session机制

$_SESSION['name'] = 'hello';//添加

$_SESSION['name'] = 'world';//修改

var_dump($_SESSION['name']);//获取

unset($_SESSION['name']);//删除

浏览器端存储session_id
  1. 是一个普通的cookie变量,变量名:PHPSESSID
  2. 两种情况:
    2.1 浏览器没有session_id时:浏览器请求服务器端,服务器php开启了session机制,PHP就会生成一个session_id,以cookie的形式设置在浏览器端:
    2.2 浏览器存在session_id时:浏览器请求服务器端,服务器php开启了session机制,PHP不会生成一个session_id
服务器端session会话数据区
  • 默认,每个session会话数据区,就是一个独立的文件。存储于 服务器所在操作系统的临时目录中
  • 如果有多个会话,则会出现多个不同session_id为文件名的文件
语法问题
1、多数据类型的支持:
  • PHP内部存储机制会先将各种类型的session变量通过serialize()先进行序列化操作,然后再存储在以session_id为名称的文件名中,(同理:程序获取session变量之前,PHP会自动使用unserialize()进行反序列化操作)
  • 在session中存储对象时,获取该对象时,需要找到对象对应的类(要提前加载进来)
2、开启session
  • 自动开启:
    1 . 配置php.ini文件中的参数session.atuo_start = 1
    2 . 使用函数ini_set('session.auto_start',1)

  • 重复开启
    1:session不能重复开启。一旦重复开启,后边的开启会被忽略!但是,会触发一个 notice 级别的错误。
    2:通常的解决方案,开启session时,增加@,错误屏蔽!

session_start();
@session_start();
3、session属性
  • 理解:
    1:因为cookie中存储session_id值,决定了对应的session数据的属性。所以cookie中的数据属性与session的一致。
    2:通过设置cookiesession_id这个cookie变量属性来改变session数据的属性

方法一 :配置php.ini中sessio.cookie_*变量(例如:session.cookie_lifetime=0
方法二 :在开启session之前使用ini_set()用于设置某个PHP配置选项
方法三 :在开启session之前使用函数session_set_cookie_params(有效期,有效路径,有效域,是否仅安全连接传输,是否HTTPONLY)
—————–(建议使用后两种,因为只会对当前文件产生影响)

4、session数据区的操作

只有开启session机制,才能够访问session数据区,对其进行操作

5、重写session的存储机制
  • 理解:
    1:session数据区默认以 文件的形式存储在服务器操作系统临时目录中
    2:当 session数据区过多时,文件形式的存储,操作速度变慢。磁盘的读写(IO,input/output)开销是很大的。
    3:实际项目中,都会采用其他的方式更快地存储session数据。典型的办法:数据库(mysql),内存(redis、memcache)。

  • 步骤:

  • 步骤 1: 通过以下这个函数告知session机制,在需要读写时,使用用户自定义的读写函数完成。
session_set_save_handler(
    开始函数,结束函数,读函数,写函数,删除函数,GC函数
);
//用来将用户自定义的函数,设置成session存储相关的函数。

注意:以上的语法,仅仅是设置告知,不是调用以上6个函数,这六个函数,在session机制运行到某个时间点时,才会被调用!

  • 步骤二 :如何设置这些函数

读函数:
1:读取和返回session数据
2:接受传递的session_id 参数(用来识别对应的数据区)
3:如果没有读取到,返回空字符串即可

function sessRead($sid){//对应2
    $sql = "SELECT sess_data FROM session WHERE id = $sid "
    $row = $DB->query($sql,'One');//对应1
    if($row){
        return $row;//返回数据
    }else{
        return "";//对应3
    }
}

写函数:
1 . 接受session_id和 需要写入的内容(serialize序列化好的)两个参数
2 . 将数据存储起来

function sessWrite($sid,$sess_str){
    $sql = "replace into session values('$sid','$sess_str')";
    return $DB->exec($sql);
}

删除操作:
1 . 接受session_id参数
2 . 销毁session,删除对应的session数据区,同时关闭session机制

function sessDelete($sid){
    $sql = "delete from session where sid = '$sid'";
    return $DB->exec($sql);
}

垃圾回收操作:
1 . 删除服务器上过时的session数据

  • 垃圾判断:
    1:设定一个有效期(默认是在php.ini中设置session.gc_maxlifetime=1440)
    2 :记录最后一次写入的时间
    3 :如果当前时间减去最后一次写入时间大于有效期时间,则为垃圾

解决方案:
1 . 在session表添加一个字段用来存储最后写入时间
2 . 通过 当前时间-写入时间 > 有效期 来判断是否为垃圾

  • 垃圾删除
    1 . 在 session_start()过程中,开启session机制过程中,有几率地执行垃圾回收操作。(几率 = session.gc_probability 除以 session.gc_divisor,所以可以通过设置这两个参数来改变几率)
    2 . 接收一个有效期参数(session.gc_maxlifetime)
    3 . 一旦执行,就会删除所有的过期的垃圾数据区。
function sessionGC($maxlifetime){
    $sql = "DELETE FROM session WHERE $maxlifetime < unix_timestamp() - $last_time ";
    return $DB->exec($sql);
}

开始操作:
1 . 可保证在第一个执行。将初始代码,在sessBegin完成,例如初始化数据库


结尾操作
1 . 进行扫尾工作


重写session存储机制2
  • 要求:php>=5.4
bool session_set_save_handler ( SessionHandlerInterface $sessionhandler [, bool $register_shutdown = true ] );
  • session存储接口
    这里写图片描述
  • 案例:
class  MySessionHandler  implements  SessionHandlerInterface
{
    private  $savePath ;

    public function  open ( $savePath ,  $sessionName )
    {
         $this -> savePath  =  $savePath ;
        if (! is_dir ( $this -> savePath )) {
             mkdir ( $this -> savePath ,  0777 );
        }

        return  true ;
    }

    public function  close ()
    {
        return  true ;
    }

    public function  read ( $id )
    {
        return (string)@ file_get_contents ( " $this -> savePath /sess_ $id " );
    }

    public function  write ( $id ,  $data )
    {
        return  file_put_contents ( " $this -> savePath /sess_ $id " ,  $data ) ===  false  ?  false  :  true ;
    }

    public function  destroy ( $id )
    {
         $file  =  " $this -> savePath /sess_ $id " ;
        if ( file_exists ( $file )) {
             unlink ( $file );
        }

        return  true ;
    }

    public function  gc ( $maxlifetime )
    {
        foreach ( glob ( " $this -> savePath /sess_*" ) as  $file ) {
            if ( filemtime ( $file ) +  $maxlifetime  <  time () &&  file_exists ( $file )) {
                 unlink ( $file );
            }
        }

        return  true ;
    }
}

$handler  = new  MySessionHandler ();
session_set_save_handler ( $handler ,  true );
session_start ();


注意:

  1. 先设置在开启session机制
  2. session_set_save_handler()先于session_start()被调用。
  3. 不要自动开启session!(session.auto_start = 1),否则会导致不能直接在程序里执行session设置操作
  4. 建议将配置session.save_handler=file 改为 user: 表示用户自定义

相关配置

1.session.save_handler: 存储处理器(files|user 文件|用户自定义)
2. session.save_path : 存储地址
3. session.cookie_XXX : (lifetime,path,domain,secure,httponly)存储session_id这个COOKIE变量的属性
4. session.gc_maxlifetime:session变量的有效期
5. session.gc_probability:session垃圾回收概率的被除数
6. session.gc_divisor:session垃圾回收概率的除数(基数)

session立即回收概率 = session.gc_probability / session.gc_divisor


session和cookie联系

  1. 都是会话技术
  2. session基于cookiesession_id存储于cookie

session和cookie区别

类型Cookiesession
存储位置浏览器端服务器端
安全性
大小限制没有
数据类型字符串全部
有效期使用长时间存储几乎不做持久化

session持久化

  • 浏览器存储session_id的cookie :session_set_cookie_params(PHP_INT_MAX);
  • 服务器session数据区有效期修改:ini_set(‘session.gc_maxlifetime’, PHP_INT_MAX);

浏览器禁用cookie、session

  • 设置session配置变量
//不仅用cookie传输session_id
ini_set('session.use_only_cookie','0');
//允许用url或表单等方式自动传输session_id
ini_set('session.use_trans_id','1');
  • 通过 url 向服务器端传输session_id

http://www.web.com/index.php?PHPSESSID=o0sdfdsfdsfdfd…”

  • 通过表单服务器端传输session_id
<input type="hidden" name="PHPSESSID" value="o0sdfdsfdsfdfd..." />
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值