1.会话控制是什么
对人来说,会话就是人与人之间的交谈;对电脑来说,所谓的会话就是设备与设备之间的交互。即用浏览器访问网站时,启用会话控制在网站上跟踪一个变量,通过这个变量,系统能识别出相应的用户信息,有了这些信息,就可以做到获取登录状态、自动登录、购物车、网上购票等一系列操作,就像人们拿着自己的身份证过安检一样。
2.为什么需要会话控制
我们在浏览网站时访问每一个页面都需要用到HTTP协议实现,而HTTP协议是无状态、无连接协议,即HTTP协议没有一个内建机制来维护两个事务之间的状态。当一个用户请求一个页面后再请求同一个网站的另一个页面时,HTTP协议不能告诉我们这两次请求来自同一个用户,会当作独立请求看待,而不会将两次访问联系在一起,会话控制能改变这种状态。
3.会话控制的两种方式
(1).COOKIE
cookie是将用户信息保存在客户端的技术,它通过将数据保存在客户端来实现与服务端保持连接。
cookie在客户端的存放有两种类型:一种是放在内存里(设置cookie的时候不设置失效时间),一种是放在硬盘里(设置cookie的时候设置失效时间)。内存cookie是用浏览器维护,保存在内存中,随着浏览器的关闭而消失,存在时间短暂。硬盘cookie保存在硬盘中,有一个过期时间,除非用户手动清除或者到了过期时间,否则硬盘cookie不会被删除,存在时间是长期的。
硬盘cookie存放位置:
猎豹浏览器:C:\Users\用户名\AppData\Local\liebao\User Data\Default\Cookies
Chrome浏览器:C:\Users\用户名\AppData\Local\Google\Chrome\User Data\Default\Cookies
Firefox浏览器:C:\Users\用户名\AppData\Roaming\Mozilla\Firefox\Profiles\a1trmm6p.default\cookies.sqlite
IE浏览器:C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Cookies
(2).SESSION
session是将用户信息保存在服务端的技术,它通过将数据保存在服务端来实现保持连接。
session原理:当我们用浏览器首次访问某个网站时,由于是第一次与该网站建立连接,网站没有关于我们的任何信息,因此服务端在处理完数据返回给客户端的时候,会在自己的内存里创建一个新的变量session_id,并把该变量发送给客户端。当再次访问该网站时,浏览器都会携带session_id,这样服务端就会认识我们了,知道是哪个浏览器发的请求,我们也可以根据session_id里的会话信息(session_id里可以存放各种会话信息,这些信息都会经过序列化之后存放),来认领自己的信息。
有两种方法让客户端拿到session_id,一种是通过cookie,一种是通过把值嵌入网页传给客户端。也有两种方法让客户端把session_id发给服务器来拿自己的信息,一种是通过cookie,一种是通过标准的Query String/POST。
一般都用cookie来发送接收,其搭建会话的过程为:首次访问某个网站时,服务端还没设置过cookie,即该网址没有向当前客户端写过cookie,所以没有cookie发送给服务端,服务端在处理完数据返回的时候,会将一个name为sessionid,value为一连串N位字符的cookie发送给客户端,后面客户端再次访问该网站时,也会带上该cookie来访问服务端。
session的存放位置:一般是在服务器的/tmp目录里,好比如我用wampserver集成环境做开发,那么session就存在\wamp64\tmp
4.PHP中设置cookie的方法
php提供了一个bool型函数来设置cookie:
setcookie(
$name, //string类型,设置cookie名
$value, //string类型,设置cookie值
$expire, //int型,设置cookie有效期
$path, //string类型,设置cookie服务器路径
$domain, //string类型,设置cookie域名
$secure, //bool型,规定是否通过安全的HTTPS连接来传输 cookie,默认为false
$httponly //bool型,默认为false,如果为true,则js就无法读取cookie,增加安全性
);
该函数除了$name是必须的,其它参数都是可选的。一般来说,设置cookie只需要用到前三个参数,即setcookie($name,$value,$expire),就足够了。
5.利用cookie实现自动登录
根据给到的设置cookie的方法,进行代码实现:
<?php
//不显示提示错误
error_reporting(E_ALL &~ E_NOTICE);
//第一次登陆时,通过用户输入的信息连接数据库确认用户,并设置cookie
if ($_POST['username'] != null && $_POST['password'] != null){
$username = trim($_POST['username']);
$password = md5(trim($_POST['password']));
$conn = mysqli_connect('localhost', 'root', '', test2);
if ($conn->connect_error){
exit('数据库连接失败:'.$conn->connect_error);
}else{
mysqli_query($conn, 'set names utf8');
$sql = "select * from user where username = '$username'";
$result = $conn->query($sql);
if ($result->num_rows > 0){
$row = $result->fetch_assoc();
if ($row['password'] == $password){
//密码验证通过,设置cookie,把用户名和密码保存在客户端
setcookie(
'username', //该cookie名为username
$username, //该cookie值
time()+60*60*24*30 //设置时效一个月,一个月后失效
);
setcookie(
'password',
$password,
time()+60*60*24*30
);
//最后跳到欢迎页面
header('location:welcome.php'."?username=$username");
}else{
exit('密码错误');
}
}else{
exit('没有该用户');
}
}
}
//再次访问时通过cookie识别用户,完成自动登录
if ($_COOKIE['username'] != null && $_COOKIE['password'] != null){
$username = $_COOKIE['username'];
$password = $_COOKIE['password'];
//连接数据库获取用户信息
$conn = mysqli_connect('localhost', 'root', '', 'test2');
if ($conn->connect_error){
exit('数据库连接失败:'.$conn->connect_error);
}else{
mysqli_query($conn, 'set names utf8');
$sql = "select * from user where username = '$username'";
$result = $conn->query($sql);
$row = $result->fetch_assoc();
if ($row['password'] == $password){ //验证后跳转
header('location:welcome.php'."?username=$username");
}
}
}
?>
<html>
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
<form action="" method="post">
用户名:<input type="text" name="username" /><br />
密码:<input type="password" name="password" /><br />
<input type="submit" value="登录">
</form>
</body>
</html>
注意:实际开发中,不能把用户名和密码放在cookie里,因为这并不安全,任何重要的用户信息,都不要放在cookie里!上例只能自己玩玩,加深理解。
6.PHP创建session步骤
启动会话-注册会话-使用会话-注销会话
(1).首先是启动会话,即开启session:
session_start(); //该函数没有参数,是bool型函数,可用该函数启用新会话或者重用现有会话
(2).注册会话,即添加session数据:
$_SESSION['username'] = 'pan'; //_SESSION变量是一个数组
(3).使用会话,即读取session数据:
$username = $_SESSION['username'];
(4).注销会话,即销毁session数据,主要有以下三种方法:
unset($_SESSION['username']); //销毁单个会话数据,不要unset($_SESSION),会导致后续无法使用$_SESSION这个变量
$_SEESION = array(); //赋空数组给$_SEESION,一次注销所有的会话变量
session_destory(); //销毁所有和当前session有关的资料
7.利用session实现自动登录
由于session是存在服务端的,远程用户无法修改session文件的内容,因此可以设置一个会话变量$_SESSION['admin']来判断用户是否自动登录(值为true就自动登录),这样做要比单纯用cookie安全,并且相比与cookie每次验证都要对比数据库,用session会减少数据库的操作,如果需要取消用户自动登录,注销会话就行。下例:
<?php
//不显示提示错误
error_reporting(E_ALL &~ E_NOTICE);
session_start();
if ($_POST['username'] != null && $_POST['password'] != null){
$username = $_POST['username'];
$password = md5($_POST['password']);
$conn = mysqli_connect('localhost', 'root', '', 'test2');
if ($conn->connect_error){
echo '数据库连接失败:'.$conn->connect_error;
}else{
mysqli_query($conn, 'set names utf8');
$sql = "select * from user where username = '$username'";
$result = $conn->query($sql);
$row = $result->fetch_assoc();
if ($row['password'] == $password){
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
$_SESSION['admin'] = true;
header('Location:welcomein.php');
}
}
}
$admin = false; //防止全局变量造成安全隐患
if (isset($_SESSION['admin']) && $_SESSION['admin'] === true){
header('Location:welcomein.php');
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
<form action = "" method="post">
用户名:<input type="text" name="username" /><br />
密码:<input type="password" name="password" /><br />
<input type="submit" value="登录">
</form>
</body>
</html>
实际开发中,session结合cookie使用是最方便的,利用cookie,我们可以设置session的生命周期、session_id()等:
<?php
session_start();
setcookie(session_name(), session_id(), time()+60*60*24*30, "/");
?>
当然了,cookie和session能做到的远不止这些,还有像购物车、网上购票等都是其使用场景,这里就不多叙述了。