PHP中的会话技术2---session

前面所提到的cookie技术,由于其存储于浏览器并且为明文存储,因此其在安全性不好,同时浏览器携带cookie数据请求时,会降低网络速度。

在此基础上使用会话技术---session。

        浏览器发出请求后,在服务器响应时,可以设置session会话数据区(用来存储当前会话的全部数据),该数据区时独立的以文本的形式存储于当前服务器的temp文件夹(windows系统的临时文件夹)中。每个会话数据区在存储时会生成一个代表数据区的唯一标识符,并且该标识符在服务器将处理完数据后返回浏览器时,会将该唯一的标识符以cookie数据的形式存储于浏览器端。后面再浏览器再次请求时,会将该cookie的标识符携带到服务器端,通过该标识符与服务器端存储的session数据区相配对,通过这种方式完成会话。

                   

实现语法:

        1.开启session机制:session_start():函数开启;

        2.利用$_SESSION操作session数据:操作$_SESSION与操作普通数组一样。

	session_start();
	$_SESSION['is_login']='yes';

通过上面程序设置session数据。我们可以在下面的结果中看到浏览器中的cookie数据区存在一个PHPSESSID名的数据。该数据的值即session数据区的唯一标识符。

                 

session中的属性:和cookie的属性类似,

        1.有效期:和cookie一样,默认为会话周期结束。

        2.有效路径:默认为整站有效。

        3.有效域:当前域有效(未设置时,子域也无法访问)。

        4.是否仅安全连接:默认与cookie一样,false。

        5.是否仅为HTTP使用:由于session存储于服务器中,因此浏览器的脚本无法获取。

注意:session数据的属性都是由浏览器端cookie中所存储的PHPSESSID变量的特征所导致的。这里要说明的一点是:在session数据被创建后,它是以文件的形式存储于临时文件目录中的,即使是当前会话结束也不会被删除,这是会话结束后无法再找到该session数据是因为浏览的端的cookie数据失效了,导致找不到与session对应的id。

因此要修改session数据的属性,就需要修改cookie数据中的PHPSESSID的属性:

        1.更改php.ini配置文件(不建议)。

        2.在脚本中,使用ini_set()来进行配置的修改,仅在设置后的脚本周期类有效,并且需要在开启session前设置完毕。

        3.使用特定功能的函数:session_set_cookie_params('有效期','有效路径','有效域','是否仅安全传输','是否HTTPONLY')完成设置。

session相关机制:session_start()开启session机制

            第一步:确定session-id。

                                 

            第二步:初始化$_SESSION

<?php
var_dump($_SESSION);
session_start();
var_dump($_SESSION);

第一个var_dump($_SESSION)提示未定义变量,表名该变量初始时不存在的,只有当session_start()后开启session,$_SESSION才会存在,如第二个var_dump($_SESSION)就会显示出空数组。

                           

            第三步:session数据的持久化(脚本周期结束后完成,没结束前不会有相应的文本数据)

                                                

session销毁

            session_destory();作用:1.删除当前session对应的数据区数据。

                                                    2.关闭session机制

            注意:这里只是删除了数据区数据,但是$_SESSION已存在的数组数据并不会消失,并且关闭session机制保障了,脚本周期结束后,系统不会将$_SESSON中的数据持久化。(如果在销毁后再次使用session_start(),结束时会再次持久化$_SESSON数据)。

                        清空session数据可以使用:$_SESSION=array();利用空数组清空。

重写session存储机制:

        通过定义相关的存储处理函数,将其设置为session机制需要的存储函数(与定义自动掉用函数相似);

        使用PHP中的函数:session_set_save_handler(开始处理(函数名,可自定义),结束处理,读取处理,写入处理,删除处理,垃圾回收处理);它包含留个参数,按照顺序为存储机制对应各个功能,其函数名可以自定义。函数定义的时候可以不存在顺序,但是session_set_save_handler()声明各个函数功能是的参数顺序不能变。

<?php
public function sessionBegin(){
	
}
public function sessionEnd(){
	
}
public function sessionRead(){
	
}
public function sessionWrite(){
	
}
public function sessionDelete(){
	
}
public function sessionGC(){
	
}
session_set_save_handler(
'sessionBegin',
'sessionEnd',
'sessionRead',
'sessionWrite',
'sessionDelete',
'sessionGC'
);

正常情况下,session开启的操作顺序是:sessionbegin->sessionread->sessionwrite->sessionend.至于sessiondelete是在调用session_destory()是才调用的。而sessionGC这是在sessionRead之后按照一定概率执行。

各个函数的实现。:

开始和结束:

<?php
//在数据库中记录对应的session文件。
create table `session`(
	session_id varchar(32) not null default '' primary key,
	session_content text,
        laster_time int not null default 0 
	)charset=utf8;
public function sessionBegin(){
	//session开启时调用
}
public function sessionEnd(){
	//session关闭时调用。
}
从数据库读取数据区:
/**
*session机制开启过程中执行,目的是从当前session数据区读取内容。
*@param $sess_id string 依靠id读取内容
*@return string 返回一个数据内容
**/
public function sessionRead($sess_id){
	//初始化数据库服务器;
	$link=mysql_connect('localhost','root','root')or die('连接失败!');
	mysql_query('set names utf8');
	mysql_query('use 数据库名');
	//查询
	$sql="select session_content from `session` where session_id=$sess_id";
	$result=mysql_query($sql);
	if($reocrd=mysql_fetch_assoc($result)){
		return $record;
	}else{
		return '';//没有对应的id,返回空字符串。
	}
}

将数据写入数据库(持久化数据)

/**
*当前脚本周期结束时,处理脚本的session数据,持久化存储到数据库中。
*@param $sess_id  需要操作的session数据的id
*@param  $sess_content 序列化号的session内容(字符串)。
*return bool 判断是否写入成功。
**/
public function sessionWrite($sess_id,$sess_content){
	//初始化数据库服务器;
	$link=mysql_connect('localhost','root','root')or die('连接失败!');
	mysql_query('set names utf8');
	mysql_query('use 数据库名');
	//写入(持久化存储)。
	$sql="replace into 数据库名 values ('$sess_id','$sess_content')";//replace语法与insert一样,主键存在(冲突)则替换,不存在则插入
	return mysql_query($sql);//
}

删除数据库中的session数据:在调用session_destory()时会自动调用。

/**
*删除操作:用户调用session_destroy($sess_id)时,销毁session数据。(删除数据区数据)
*@param  $sess_id session的id
*@return bool 返回一个删除操作结果。
**/
public function sessionDelete($sess_id){
	//初始化数据库服务器;
	$link=mysql_connect('localhost','root','root')or die('连接失败!');
	mysql_query('set names utf8');
	mysql_query('use 数据库名');
	//删除数据库中的session数据。
	$sql="delete from 表名 where $sess_id=session_id";
	if(mysql_query($sql)){
		return true;
	}else{
		return false;
	}
}

垃圾回收函数重写:

        垃圾识别,可以给数据库添加一个时间类型数据,记录其最后一次处理后时间戳。如果登入后,间隔上次时间超过规定时间(多久未登入),则被视为垃圾数据,删除。

        ‘最后一次更新’可以在写操作将其更新。

$sql="replace into 数据库名 values ('$sess_id','$sess_content',unix_timestamp())";

GC执行:在开启session机制过程中,有一定概率在执行完读取操作后执行垃圾回收操作。

                这里的一定概率是指在配置文件中设置的session.gc_probability(分子)和session.gc_divisor(分母)来进行概率设定。

/**
*开启session机制时,有一定概率删除那些过期的session数据区。
*@param $life_time 数据存在的生命周期。
*return bool 返回数据库操作结果。
**/
public function sessionGC($life_time){
	//初始化数据库服务器;
	$link=mysql_connect('localhost','root','root')or die('连接失败!');
	mysql_query('set names utf8');
	mysql_query('use 数据库名');
	//删除数据库中过期的session数据。
	$sql="delete from 表名 where last_time<unix_timestamp()-$life_time";
	return mysql_query($sql);
}

注意:对于上面的函数使用session_set_save_handler()声明时,参数为函数名即可

session_set_save_handler(
'sessionBegin',
'sessionEnd',
'sessionRead',
'sessionWrite',
'sessionDelete',
'sessionGC'
);
        但是当把上面的重写操作作为类使用时,里面的名字为方法名。这是如果用session_set_save_handler()进行声明时,是对类中的方法进行声明。这是需要其对应方法的对象。
session_set_save_handler(
array($this'sessionBegin'),
array($this'sessionEnd'),
array($this,'sessionRead'),
array($this,'sessionWrite'),
array($this,'sessionDelete'),
array($this,'sessionGC')
);
设置session处理器

        设置配置文件中的session.save_handler来对其存储方式进行设定。

        原文件中的session.save_handler=files表示将session数据存储在临时文件夹的文本文件中。

        当我们重写session存储机制后,最后通过ini_set('session.save_handler','user');来表示用户自定义session机制。

        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值