session是什么?
session即会话,指一种持续性的、双向的连接,session和cookie在本质上没有什么区别,都是针对http协议的局限性而提出的一种保持客户端和服务端会话连接状态的机制。
session工作原理
session通过一个称为PHPSESSID
的Cookie和服务器联系,session是通过sessionID
判断客户端用户(即session文件的文件名)
sessionID的传递方式:通过URL或者通过cookie携带
当第一次访问网站时,seesion_start()
函数就会创建一个唯一的Session ID
,并自动通过HTTP的响应头,将这个Session ID保存到客户端Cookie
中。同时,也在服务器端创建一个以Session ID命名的文件
,用于保存这个用户的会话信息。当同一个用户再次访问这个网站时,也会自动通过HTTP的请求头将Cookie中保存的Seesion ID再携带过来,这时session_start()函数就不会再去分配一个新的session ID,而是在服务器的硬盘中去寻找和这个Session ID同名的Session文件,将这之前为这个用户保存的会话信息读出,在当前脚本中应用,达到跟踪这个用户的目的。
session的使用
USAGE
//开启session
session_start();
//设置session数据,执行后会在php.ini的session.save_path属性指定的目录下生成一个以sessionID为名字的文件(如果是文件存储session方式)
$_SESSION["username"]="mayy";
$_SESSION["phone"]="131322";
//删除单个session中注册的单个变量,如果删除整个session,使用 $_SESSION = array();
unset($_SESSION["phone"]);
//消除session时也需要清除Cookie中保存的sessionID
if(isset($_COOKIE[session_name()])){
setcookie(session_name(),'',time()-3600,'/');
}
//彻底销毁session
session_destroy();
和设置
cookie
一样,session_start()必须在输出内容前执行。或者使用ob_start()
来控制一下。
session生存期的设置
//1、利用Cookie保存session的机制
$lifeTime = 24*3600;
setcookie(session_name(),session_id(),time()+$lifeTime, '/');
//2、使用函数session_set_cookie_params()设置
$lifetime=24*3600;
session_set_cookie_params($lifetime);
session_start();
session的垃圾回收机制
PHP一定提供了一种session过期回收机制。在php.ini
中
session.gc_maxlifetime=1440 #默认生存时间为1440s
如果session文件过期了,在下一次session回收的时候就会被回收,回收机制配置如下:
session.gc_probability=1
session.gc_divisor=1000
意思是每1000次PHP请求就有一次回收发生。概率是 gc_probability/gc_divisor。
与此同时还可以通过控制保存sessionID的cookie
的过期:
session.cookie_lifetime=0
这个值默认是0,代表浏览器一关闭SESSIONID就失效,可以把session.gc_maxlifetime
和session.cookie_lifetime
设置成同一个值就可以控制session的失效时间了。
session入库
对于访问量大的站点,默认的文件存储方式会导致大量文件占用磁盘,较好的方法是用入库,但是大量数据库的连接、读写也会产生较大开销,更进一步的处理是利用memcache、redis之类的方式存储。都是通过注册session的处理机制来实现的
bool session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc [, callable $create_sid ] )
USAGE
- 创建session数据表
CREATE TABLE `session` (
`session_id` varchar(255) NOT NULL,
`session_data` blob,
`session_time` int(11) NOT NULL,
PRIMARY KEY (`session_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- 注册自定义session机制
ini_set("session.save_handler","user");
//设置用户自定义会话存储函数及执行方法
session_set_save_handler( "open","close","read","write","destroy","gc" );
//连接数据库
function open(){
@$link = mysql_connect('127.0.0.1', 'root', 'root');
mysql_query('set names utf8');
mysql_query('use session');
}
function close(){
mysql_close();
}
function read($sess_id){
$sql = "select session_data from `session` where session_id = '$sess_id'";
$result = mysql_query($sql);
if($rows = mysql_fetch_assoc($result)){
return $rows['session_data'];
}else{
return '';
}
}
function write($sess_id,$sess_data){
$sql = "insert into `session` (session_id,session_data,session_time) values('$sess_id','$sess_data', now()) on duplicate key update session_data = '$sess_data' , session_time = now()";
return mysql_query($sql);
}
function destroy($sess_id){
$sql = "delete from `session` where session_id = '$sess_id'";
return mysql_query($sql);
}
function gc($sess_id){
$sql = "delete from `session` where now()-session_time > '1440' ";
return mysql_query($sql);
}
session入redis
待续…
PHP操作session的常用函数
session_start([array $option])
:开启sessionsession_name([string $name])
:读取/设置会话名称session_id ([string $id ])
:读取/设置当前会话IDsession_unset()
:释放所有的会话变量,如果使用的是 $_SESSION,请使用unset($_SESSION['varname'])
来释放,要注意不要使用 unset($_SESSION)释放整个$_SESSIONsession_destroy()
:销毁当前会话中的全部数据
php.ini相关配置
-
session.save_handler = file
用于读取/回写session数据的方式,默认是files,可以设置成user,实现入库 session.save_path =“/var/lib/php/session”
指定保存session的目录,该目录需要手动创建并注意权限。还可以写成这样session.save_path =“N;/path”
其中N是整数。这样使得不是所有的session文件都保存在同一个目录中,而是分散在不同目录。这对于服务器处理大量session文件是很有帮助的。(注:目录需要自己手工创建)session.auto_start = 0
自动开启session机制,建议关闭
参考: 《PHP核心技术与最佳实践》