精选30+云产品,助力企业轻松上云!>>>
- 目录
- 1. 前言
- 2. SESSION的使用
- 2.1 session简介及工作原理
- 2.2开启会话session_start()
- 2.3设置会话$_SESSION
- 2.4销毁session
- 3. session实战演示
- 3.1使用session保存验证码
- 4.自定义会话管理器
- 4.1案例:保存session数据到数据库中
- 4.1.1创建存储数据表
- 4.1.2存储session接口类
- 4.1.3测试存储session接口类
- 5. 总结
1.前言
session是存储在服务端的会话,通过使用session技术,能够很好地帮助我们与客户端进行验证通信,另外,session也是一个高频面试点,因此我们很有必要掌握它。
代码分享:https://github.com/mtdgclub/SeCo
2.SESSION的使用
2.1 session简介及工作原理
会话就是服务器和浏览器保有的共同的小秘密的这段时间.
工作原理如下图所示:
- 准备建立会话的时候,PHP会先查看请求是否包含Seesion_id,如果没有服务器会在自己的内存里创建一个新的变量,这个变量就是session_id
- 服务器会把这个session_id发送到浏览器保存,一般浏览器会把这个ID保存到cookie中
- 之后浏览器每次再去访问服务器的时候,都会携带cookie中存储的seesion_id,这样服务器就能够认识到对应的客户端
- 服务器的session_id可以存放任意的会话数据,这些数据是经过序列化的
- 每个浏览器都能够凭借session_id到服务器认领自己的信息
- 如果要销毁会话,可以删除会话的数据,销毁会话文件
2.2开启会话session_start()
代码举例:
header('content-type:text/html;charset=utf-8');
//开启会话
session_start();
2.3设置会话$_SESSION
//设置数据
$_SESSION['username']='fangzhijie';
$_SESSION['email']='[email protected]';
$_SESSION['age']=22;
在控制器查看session内容
可以在php.ini文件查看session配置选项
- session.save_handler设置用户自定义会话存储函数
- session.save_path读取/设置当前会话的保存路径
- session.name读取/设置会话名称,只能由字母数字组成,默认是PHPSESSID
- session.auto_start设置自动开启session_start(),默认为0不开启
//通过服务器得到session_id的名字
echo 'SESSION的名字:',session_name(),'
';
echo 'SESSION的ID:',session_id(),'
';
//使用cookie将session长期保存到客户端
session_start();
$_SESSION['username']='fangzhijie';
$_SESSION['email']='[email protected]';
setcookie(session_name(),session_id(),time()+3600);
- session.use_cookies指定是否在客户端用cookie来存放会话ID,默认为1(启用)
- session.user_only_cookies指定是否在客户端仅仅使用cookie来存放会话ID,启用可以防止有关通过URL传递会话ID的攻击,默认是1(启用)
- session.use_trans_sid指定是否启用透明SID支持,默认为0(禁用)
疑问:
当用户禁用掉cookie,我们的session_id是否可以传递session
分析:
如果我们通过“浏览器->设置->隐私->关闭cookie”会发现,当用户禁用掉cookie情况下是得不到session_id的,那么,这种情况我们如何获取session?
解答:
能够通过URL的形式传递session_id过去
传递代码:
session_start();
$_SESSION['name']='fangzhijie';
$_SESSION['age']='22';
echo "查看信息";
得到代码:
session_id($_GET[session_name()]);
session_start();
print_r($_SESSION);
2.4销毁session
一共有以下三种方法:
- 将$_SESSION清空,$_SESSION=[]
- 将cookie中数据清除,setcookie()
- 销毁会话session_destory()
PS:为了彻底销毁会话,比如在用户退出登录时候,必须同时重置会话ID;如果是通过cookie方式传送会话ID的,那么同时也要调用setcookie()函数删除客户端会话cookie
代码举例:
//初始化,并开启会话
session_start();
//重置所有变量
$_SESSION=array();
//销毁会话中数据,同时销毁会话本身
if(ini_get('session.user_cookies')){
$params=session_get_cookie_params();
setcookie(session_name(),'',time()-42000,
$params['path'],$params['domain'],
$params['secure'],$params['httponly']
);
}
//最后,销毁会话
session_destroy();
3. session实战演示
3.1使用session保存验证码
/**
* 产生验证码
* @param int $type 类型0纯数字 1字母 2数字+字母
* @param int $length 长度
* @param int $width 宽度
* @param int $height 高度
* @return string 真实验证码字符串
*/
function generateVerity($type = 0, $length = 4, $width = 100, $height = 30)
{
//创建黑色画布
$image = imagecreatetruecolor($width, $height);
//定义画布背景色
$bgcolor = imagecolorallocate($image, 255, 255, 255);
//填充颜色
imagefill($image, 0, 0, $bgcolor);
$str = '';
$captcha = "";
switch ($type) {
case 0:
$str = join('', array_rand(range(0, 9), $length));
break;
case 1:
$str = join('', array_rand(array_flip(array_merge(range('a', 'z'), range('A', 'Z'))), $length));
break;
case 2:
$str = join('', array_rand(array_flip(array_merge(range(0, 9), range('a', 'z'), range('A', 'Z'))), $length));
break;
}
for ($i = 0; $i < $length; $i++) {
// 字体大小
$fontsize = 10;
// 字体颜色
$fontcolor = randColor($image);
$captcha .= $fontcontent = $str;
// 显示的坐标
$x = ($i * 100 / 4) + mt_rand(5, 10);
$y = mt_rand(5, 10);
// 填充内容到画布中
imagestring($image, $fontsize, $x, $y, $fontcontent, $fontcolor);
}
//4.3 设置背景干扰元素
for ($$i = 0; $i < 200; $i++) {
$pointcolor = imagecolorallocate($image, mt_rand(50, 200), mt_rand(50, 200), mt_rand(50, 200));
imagesetpixel($image, mt_rand(1, 99), mt_rand(1, 29), $pointcolor);
}
//4.4 设置干扰线
for ($i = 0; $i < 3; $i++) {
$linecolor = imagecolorallocate($image, mt_rand(50, 200), mt_rand(50, 200), mt_rand(50, 200));
imageline($image, mt_rand(1, 99), mt_rand(1, 29), mt_rand(1, 99), mt_rand(1, 29), $linecolor);
}
header('Content-Type:image/png');
imagepng($image);
imagedestroy($image);
return $captcha;
}
function randColor($image)
{
//字体颜色
return imagecolorallocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
}
//调用
session_start();
$_SESSION['verityCode'] = generateVerity();
4.自定义会话管理器
如果访问用户有千万级别,而seesion还是设置文件形式保存,那么就会产生千万数量的session文件,访问速度就很慢,那么此时我们可以改变存储的形式;我们可以改为存储到数据库,但是数据库访问量大了,还是不可取;因此又可保存到非关系数据库
4.1案例:保存session数据到数据库中
首先,需要使用自定义处理器,比如让数据库自定义为user
session.save_hander定义存储和获取与绘画关联的数据处理器名字
4.1.1创建存储数据表
CREATE TABLE `NewTable` ( `session_id` char(40) NOT NULL , `session_data` varchar(200) NULL , `session_expires` int(11) NULL , PRIMARY KEY (`session_id`) ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8 ;
4.1.2存储session接口类
public function write($session_id, $session_data) { $newExp = time() + $this->lifetime; $session_id = mysqli_escape_string($this->link, $session_id); //查询是否存在,存在则更新;否则则写入 $sql = " SELECT * FROM sessions WHERE id ={$session_id} "; $result = mysqli_query($this->link, $sql); if (mysqli_num_rows($result) == 1) { //更新操作 $sql = ""; } else { //新增操作 $sql = ""; } $result = mysqli_query($this->link, $sql); return mysqli_affected_rows($this->link) == 1; } public function read($session_id){ $session_id = mysqli_escape_string($this->link, $session_id); $time = time(); $sql = " SELECT * FROM sessions WHERE id ={$session_id} AND session_expires <{$time} "; $result = mysqli_query($this->link, $sql); if(mysqli_num_rows($result)==1){ return mysqli_fetch_assoc($result)['session_data']; }else{ return ''; } }
4.1.3测试存储session接口类
require_once 'session.class.php';
$sessionClass = new session();
ini_set('session.save_handler','user');
session_set_save_handler($sessionClass,true);
session_start();
$_SESSION['username'] = 'fangzhijie';
$_SESSION['age'] = 23;
$_SESSION['contract'] = 'this is a test';
$_SESSION['email'] = '[email protected]';
//打印
var_dump($_SESSION);
//清空
session_destroy();
5.总结
通过本章简要的总结和掌握了session相关的技术和知识点,如果想要更加深入了解,能够先学习http相关的知识点,这样对session和cookie的理解就更加渗透。