https://blog.csdn.net/zhouzzz000/article/details/80471137
为什么要使用Cookie
HTTP最大的特点是无连接无状态,使用Cookie和Session的技术就是为了解决这个问题,简单来说,就是让浏览器在一段时间内认识你。
Cookie
Cookie保存在客户端中
1、内存Cookie
由浏览器来维护,保存在内存中,浏览器关闭之后就消失了,存在时间短暂
2、硬盘Cookie
保存在硬盘中,有一个过期时间,除非用户手动清除或者到了过期时间,硬盘Cookie不会被删除,其存在时间是长期的
浏览器Cookie的查看
拿chrome为例,第一种是点击网址最左边的按钮或者
第二种是按F12在Application在Storage里有Cookie可以看到
Cookie使用场景
永久登陆
购物车
等等
操作Cookie
设置Cookie
setcookie()
bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool$secure = false [, bool $httponly = false ]]]]]] )
$name:指定Cookie的名字
$value: Cookie的值
$expire:设置Cookie的过期时间,默认值为0,单位为秒数,没有设置就默认为内存Cookie
$path: 设置Cookie的有效路径,默认是当前目录或者其子目录有效,也可以指定成整个根目录/,在整个根目录下有效
$domain:设置Cookie的作用域,默认在本域下
$secure:设置是否Cookie只能通过Https传输,默认值是false
$httponly:是否只是用http访问Cookie,默认值是false,如果设置成true,那么客户端的js就无法操作这个Cookie了,使用这个可以减少XSS攻击
setrawcookie()
不会对值进行urlencode编码
读取Cookie
Cookie数据保存在$_COOKIE
更新Cookie
利用setcookie重新进行赋值,$path和$domain要一致,不然会产生新的cookie值
删除Cookie
1、浏览器手动删除
2、setcookie删除
让cookie的时间过期,$path和$domain要一致
eg:setcookie('testPath1','test2',time()-1;
通过header的方法操作Cookie
header("Set-cookie:name=value[;expire=data][;domain=domain][;path=path][;secure][;httponly]")
Cookie保存数组形式的数据
<?php
//TODO:Cookie通过数组的形式保存数据
setcookie('userInfo[name]','king',time()+3600);
setcookie('userInfo[email]','muke@imooc.com',time()+3600);
setcookie('userInfo[addr]','beijing',time()+3600);
通过js操作cookie
var Cookie = {
set: function(key,value,expiresTime)
{
if(expiresTime)
{
var date = new Date();
date.setTime(date.getTime()+expiresTime);
var expiresStr = "expires="+date.toGMTString()+';';
}else
{
var expiresStr='';
}
document.cookie = key+'='+escape(value)+';'+expiresStr;
},
get: function(key)
{
var getCookie = document.cookie.replace(/[ ]/g,'');
var resArr = getCookie.split(';');
var res;
for(var i = 0,len = resArr;i < len;i++)
{
var arr = resArr[i].split('=');
if(arr[0] == key)
{
res = arr[1];
break;
}
}
return unescape(res);
}
};
封装Cookie类
<?php
/**
* Cookie的设置、读取、更新、删除
*/
class CustomCookie{
private static $_instant = null;
private $expire = 0;
private $path = '';
private $domain = '';
private $secure = false;
private $httponly = false;
private function __construct(array $options = []){
$this->setOptions($options);
}
/**
* 设置相关选项
* @param array $options Cookie相关选项
*/
private function setOptions(array $options = [])
{
if(isset($options['expire']))
{
$this->expire = (int)$options['expire'];
}
if(isset($options['path']))
{
$this->path = $options['path'];
}
if(isset($options['domain']))
{
$this->domain = $options['domain'];
}
if(isset($options['secure']))
{
$this->secure = (bool)$options['secure'];
}
if(isset($options['httponly']))
{
$this->httponly = (bool)$options['httponly'];
}
return $this;
}
/**
* 单例模式
* @param array $options Cookie相关选项
* @return object 对象实例
*/
public static function getInstance(array $options = [])
{
if(is_null(self::$_instant))
{
$class = __CLASS__;
self::$_instant = new $class($options);
}
return self::$_instant;
}
/**
* 设置Cookie
* @param $name Cookie名称
* @param $value Cookie的值
* @param array $options Cookie的相关选项
*/
public function set($name,$value,array $options=[])
{
if(is_array($options)&&count($options)>0)
{
$this->setOptions($options);
}
if(is_array($value)||is_object($value))
{
$value = json_encode($value);
}
setcookie($name,$value,$this->expire,$this->path,$this->domain,$this->secure);
}
/**
* 得到指定Cookie
* @param $name Cookie名称
* @return mixed|null 返回null对象或者标量
*/
public function get($name)
{
if(isset($_COOKIE[$name]))
{
return substr($_COOKIE[$name],0,1)=='{'?json_decode($_COOKIE[$name]):$_COOKIE[$name];
}else{
return null;
}
}
public function delete($name,array $options=[])
{
if(is_array($options)&&count($options)>0)
{
$this->setOptions($options);
}
if(isset($_COOKIE[$name]))
{
setcookie($name,'',time()-1,$this->path,$this->domain,$this->secure,$this->httponly);
unset($_COOKIE[$name]);
}
}
/**
* 删除全部Cookie
* @param array $options
*
*/
public function deleteAll(array $options=[])
{
if(is_array($options)&&count($options))
{
$this->setOptions($options);
}
if (!empty($_COOKIE))
{
foreach ($_COOKIE as $name=>$value)
{
setcookie($name,'',time()-1,$this->path,$this->domain,$this->secure,$this->httponly);
unset($_COOKIE[$name]);
}
}
}
}
$cookie = CustomCookie::getInstance();
//$cookie->set('a','1');
//$cookie->set('b',222,['expire'=>time()+3600]);
//$cookie->set('userInfo',['username'=>'zhou','age'=>23]);
//$cookie->delete('b');
$cookie->deleteAll();
Cookie的缺点
1、Cookie中不要存储敏感数据,Cookie不是很安全,截取Cookie之后可以用来Cookie欺骗
2、不要把Cookie当作客户端存储器使用,首先每个域名允许的Cookie是有限制的,根据不同的浏览器这个限制也不同,Cookie中保存数据的最大字节数是4K
3、Cookie设置之后每次都会附着在HTTP的头中一起发送,浪费带宽
Cookie练习:实现自动登陆
index.php
<?php
if (!isset($_COOKIE['username'])) {
exit("<script>
alert('请您先登陆以后访问');
location.href='login.php';
</script>");
}
//效验用户登陆凭证
if (isset($_COOKIE['auth'])) {
$auth = $_COOKIE['auth'];
$resArr = explode(':', $auth);
$userid = end($resArr);
$con = mysqli_connect('localhost', 'root', '123');
if ($con) {
mysqli_set_charset($con, 'utf8');
mysqli_select_db($con, 'test') or die("select database failed");
$sql = "select id,username,password from user where id='{$userid}'";
$res = mysqli_query($con, $sql);
if (mysqli_num_rows($res) == 1) {
$row = mysqli_fetch_assoc($res);
$username = $row['username'];
$password = $row['password'];
$salt = 'zhouzzz';
$authStr = md5($username . $password . $salt);
if ($authStr != $resArr[0]) {
exit("<script>
alert('请您先登陆以后访问');
location.href='login.php';
</script>");
} else {
}
}
} else {
die('Connect Error');
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>首页</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" media="screen" href="main.css" />
<script src=""></script>
</head>
<body>
<h1>首页</h1>
<ul>
<li><a href="#">首页</a></li>
<li><a href="#">热门技术</a></li>
<li><a href="#">欢迎您:<?php echo $_COOKIE['username']; ?></a></li>
</ul>
</body>
</html>
login.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>登陆页面</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" media="screen" href="main.css" />
<script src="main.js"></script>
</head>
<body>
<h1 class="text-center">登陆页面</h1>
<form method="post" action="validate.php">
<label for="username">用户名:</label>
<input type="text" class="form-control" name = "username" id = "username" placeholder="请输入用户名" />
<br />
<label for="password">密码:</label>
<input type="password" class="form-control" name = "password" id = "password" placeholder="请输入密码" />
<div>
<label>
<input type="checkbox" name = "autoLogin" value="1">一周内登陆
</label>
<button type="submit">立即登陆</button>
</div>
</form>
</body>
</html>
validate.php
<?php
use think\image\Exception;
$username = $_POST['username'];
$password = $_POST['password'];
$autoLogin = 0;
if(isset($_POST['autoLogin']))$autoLogin = $_POST['autoLogin'];
$con=mysqli_connect('localhost','root','123');
if($con)
{
echo 'connect successfully'.'<br/>';
mysqli_set_charset($con,'utf8');
mysqli_select_db($con,'test') or die("select database failed");
$sql = "select id,username,password from user where username='{$username}'&&password='{$password}'";
// $sql = mysqli_escape_string($con,$sql);
echo $sql;
$res = mysqli_query($con,$sql);
$row = mysqli_fetch_all($res);
var_dump($row);
if(mysqli_num_rows($res) == 1)
{
if($autoLogin == 1)
{
$row = mysqli_fetch_assoc($res);
setcookie('username',$username,time()+24*60*60);
$salt = 'zhouzzz';
$auth = md5($username.$password.$salt).":".$row['id'];
setcookie('auth',$auth,time()+24*60*60);
echo $auth;
}else{
setcookie('username',$username);
}
exit("<script>
alert('登陆成功');
location.href='index.php';
</script>");
}else{
exit("<script>
alert('登陆失败');
location.href='login.php';
</script>");
}
}
else{
die('Connect Error');
}