web服务器是基于http协议的,而http协议是无状态的,导致任意两个请求之间没有联系。但是我们登录网站后,它却能记住我们的身份,这个过程中一定使用了某个标识来区别我们的身份。对于简单数据传输的我们可以使用URL上面的GET方式和HTTP的POST方式,对于大量的数据就显得比较麻烦了,因此我们用到了COOKIE和SESSION来跟踪不同的用户。
1.COOKIE技术 :
需要浏览器参与,保存在客户端。意思就是php服务端制造一个cookie数据交给浏览器保存,然后浏览器每次访问的时候都携带这个数据,服务器再根据这个数据做出不同的响应。setcookie('name','ming'); 这句话的意思是在浏览器上设置一个变量name,值为ming,只能为字符串;它保存在浏览器上面,我们可以预定义数组变量$_COOKIE['name'] 获得。当然,这里不仅仅是$_COOKIE['name'],我们还可以获得浏览器上的其他COOKIE值。
COOKIE数据默认是临时COOKIE,也就是关闭浏览器CKKOIE随之消失. 我们可以设置它的有效期,例如:
setcookie('name','ming',time()+60*60); 设置为1个小时
setcookie('name','ming',PHP_INT_MAX); 设置为php最大时间值
COOKIE的有效路径是当前目录和后代目录。 我们可以通过第四个参数来设置
setcookie('name','ming',time()+60*60,'/'); 整站有效
在子域名之间是可以共享的
setcookie('name','ming',time()+60*60,'/','demo.php'); 在www.demo.php下所有子域名都可以访问
不能设置了马上就访问到,要等到该程序执行了,下次才能生效。
2.SESSION技术
前面的COOKIE是基于客户端的,每次请求都携带,不太安全,SESSION则是存放在服务端,它给每个客户端开辟一个空间,存放唯一标识PHPSESSID,这样就可以通过PHPSESSID来区分不同的客户端了,当浏览器第一次访问时PHPSESSID,会自动生成一个PHPSESSID,保存在COOKIE数组中。
首先开启php的session支持,在这之前不能有输出。
session_start();
SESSION['name'] = 'ming'; 设置session变量
unset(SESSION['name') 删除该session变量
$_SESSION = array() 清空所有session
session_destroy() 只删除session文件 ,不清空session变量
为了完全删除session 还需要 setcookie('PHPSESSID','',time()-1);
session默认以文件保存在服务端,存放路径可以通过php.ini session.save_path 来设置, 当session文件过多时,也可以进行配置分子目录进行保存。
服务器端垃圾判定的时间要与session持久化的时间尽量一致
数据库保存session
利用系统函数,设置session存储所需要的处理器,为当前定义好的这六个函数:
session_set_save_handler( 'sess_open', 'sess_close', 'sess_read', 'sess_write', 'sess_destroy', 'sess_gc' );
增加数据表
create table session( sess_id varchar(32) primary key, sess_data text, expire int )charset=utf8;
垃圾回收 gc
如果一条记录(一个文件) 在多久之内,没有被使用过了,则认为该数据是垃圾!
默认的时间,是1440s秒.24分钟。可以通过php.ini进行配置
什么时候执行删除的动?
在session_start()时,有一定的几率,执行垃圾回收!
默认是 1/1000.
可以通过php.ini修改
执行过程:
完整代码
<?php //定义六个函数 /** * 在session开启时执行, * 负责完成session存储所需要资源的初始化工作! */ function sess_open() { echo 'open<br>'; //连接数据库 $link = mysql_connect('127.0.0.1:3306', 'root', '123456'); mysql_query('set names utf8'); mysql_query('use database'); } /** * session_start()时,开启session时被执行 * * 负责从当前的session记录中,将session数据读取出来 * * @param $sess_id string 当前的sessionID * * @return string session的数据,不需要序列化。如果没有读到则返回空字符串! */ function sess_read($sess_id) { echo 'read<br>'; //利用 select 查询 $sql = "select sess_data from `session` where sess_id='$sess_id'"; $result = mysql_query($sql); if($row = mysql_fetch_assoc($result)) { return $row['sess_data']; } else { return ''; } } /** * 在 脚本结束时被执行 * * 负责,将当前的session数据,同步写到当前的session记录中 * * @param $sess_id string * @param $sess_data string * * @return bool */ function sess_write($sess_id, $sess_data) { echo 'write<br>'; //执行写数据的操作! //当前session记录存在则更新sess_data,不存在则插入! $expire = time(); $sql = "insert into `session` values ('$sess_id', '$sess_data', $expire) on duplicate key update sess_data='$sess_data', expire=$expire"; return mysql_query($sql); } /** * 在调用了 session_destroy()系统函数时,被自动调用! * 负责的功能时,利用当前id,删除当前的session记录! * * @param $sess_id string * * @return bool */ function sess_destroy($sess_id) { echo 'destroy<br>'; //执行 delete 操作 $sql = "delete from `session` where sess_id='$sess_id'"; return mysql_query($sql); } /** * 在session_start() 时执行 * 负责 删除所有的垃圾数据 * * @param $maxlife int 最大的生命周期 * * @return bool */ function sess_gc($ttl) { echo 'gc<br>'; // $now = time(); $last = $now-$ttl;// $sql = "delete from `session` where expire < $last"; return mysql_query($sql); } /** * 脚本结束 */ function sess_close() { echo 'close<br>'; // mysql_close(); return true; } session_set_save_handler( 'sess_open', 'sess_close', 'sess_read', 'sess_write', 'sess_destroy', 'sess_gc' );
配置php存放在memcache中
<?php ini_set("session.save_handler", "memcache"); ini_set("session.save_path", "tcp://Mem服务器1:端口号,tcp://Mem服务器2:端口号..."); ?>