学习目标
本期接上期,继续学习php.
1.Cookie的定义及作用
HTTP 很重要的一个特点就是无状态(每一次见面都是“初次见面”),如果单纯的希望通过我们的服务端程序去记 住每一个访问者是不可能的,所以必须借助一些手段或者说技巧让服务端记住客户端,这种手段就是 Cookie。
Cookie 就像是在超级市场买东西拿到的小票,由超市(Server)发给消费者(Browser),超市方面不用记住每 一个消费者的脸,但是他们认识消费者手里的小票(Cookie),可以通过小票知道消费者之前的一些消费信息(在 服务端产生的数据)。
1.1. PHP 中操作 Cookie
http://php.net/manual/zh/function.setcookie.php
1 // 设置 cookie
2 setcookie("TestCookie", "hello", time() + 1 * 60 * 60); /* 1 小时过期 */
3 // 获取 cookie
4 echo $_COOKIE["TestCookie"];
setcookie:
<?php
// 设置响应头中的 Set-Cookie 可以下发小票(给客户端发)
// Cookie 在客户端存储的是键值结构
// header('Set-Cookie: foo=bar');
// header 在设置相同的键时 会出现覆盖的情况
// header('Foo: 123');
// header('Foo: 456');
// setcookie 是专门用于设置 cookie 的函数
// setcookie('key', 'value');
// 只传递一个参数是删除
// 原理:设置过期时间为一个过去时间
setcookie('key');
// 传递两个参数是设置 cookie
setcookie('key1', 'value1');
// 传递第三个参数是设置过期时间
// 不传递就是 会话级别的 Cookie (关闭浏览器就自动删除)
setcookie('key2', 'value2', time() + 1 * 24 * 60 * 60);
setcookie('key3', 'value3', time() + 1 * 24 * 60 * 60, '/users');
setcookie('key4', 'value4', time() + 1 * 24 * 60 * 60, '', '', false, true);
getcookie:
<?php
// 专门取 cookie
// 关联数组的方式访问客户端提交过来的 Cookie
var_dump($_COOKIE);
1.1.1 cookoe的作用和其他常见概念
path 设置cookie的作用路径范围。
domain设置cookie的作用域名范围。
1.2. JavaScript 中操作 Cookie
1.2.1. Pure JavaScript
// 新增一条 cookie,注意:cookie 是有大小限制,约为 4k
// 格式固定:<key>=<value>[; expires=<GMT格式时间>][; path=<作用路径>][; domain=<作用域名>]
// 除了键值以外其余属性均有默认值,可以省略
// expires 表示 cookie 失效的时间,默认为关闭浏览器时
// path 表示 cookie 生效的路径,默认为当路径
// / /foo.php /abc/foo.php
// /foo /bar/abc.php
// domain 表示 cookie 生效的域名,默认为当前域名
document.cookie = 'name=value; expires=Tue, 10 Oct 2017 16:14:47 GMT; path=/; domain=zce.m
// 获取全部 cookie console.log(document.cookie)
// => 'key1=value1; key2=value2'
// 得到的结果是字符串,需要自己通过字符串操作解析
以下提供github大佬写的框架:
1.2.2. jQuery plugin
https://github.com/carhartl/jquery-cookie
1.2.3. without jQuery
https://github.com/js-cookie/js-cookie
2.Session
由于 Cookie 是服务端下发给客户端由客户端本地保存的。换而言之客户端可以在本地对其随意操作,包括删除和 修改。如果客户端随意伪造一个 Cookie 的话,对于服务端是无法辨别的,就会造成服务端被蒙蔽,构成安全隐 患。
于是乎就有了另外一种基于 Cookie 基础之上的手段:Session:
Session 区别于 Cookie 一个很大的地方就是:Session 数据存在了服务端,而 Cookie 存在了客户端本地,存在服 务端最大的优势就是,不是用户想怎么改就怎么改了。
Session 这种机制会更加适合于存放一些属于用户而又不能让用户修改的数据,因为客户端不再保存具体的数据, 只是保存一把“钥匙”,伪造一把可以用的钥匙,可能性是极低的,所以不需要在意。
3.不显示广告案例
index.php
<?php
if (isset($_GET['action']) && $_GET['action'] === 'close-ad') {
// 不想看到广告
setcookie('hide_ad', '1');
$_COOKIE['hide_ad'] === '1';
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.ad {
height: 200px;
background-color: #ff0;
}
.ad a {
float: right;
}
</style>
</head>
<body>
<?php if (empty($_COOKIE['hide_ad']) || $_COOKIE['hide_ad'] !== '1'): ?>
<div class="ad">
<!-- <a href="close.php">不再显示</a> -->
<a href="index.php?action=close-ad">不再显示</a>
</div>
<?php endif ?>
</body>
</html>
close.php
<?php
// 只要有人来请求我,意味着这个人不想再看到广告
// 我们给这个用户开张票
setcookie('hide_ad', '1');
header('Location: index.php');
猜数字游戏案例
参考:https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/First_steps/A_first_splash
注意:这里是 JavaScript 的实现,经供参考
建议:好好看看里面写的一些内容。
我想让你创建一个可以猜数字的游戏,它会在1~100以内随机选择一个数, 然后让玩家挑战在10轮以内猜出这个数 字,每一轮都要告诉玩家正确或者错误, 如果出错了,则告诉他数字是低了还是高了,并且还要告诉玩家之前猜的 数字是什么。 一旦玩家猜测正确,或者他们用完了回合,游戏将结束。 游戏结束后,可以让玩家选择再次开始。
index.php:
<?php
if (empty($_COOKIE['num']) || empty($_GET['num'])) {
// 在游戏开始时执行生成随机数
$num = rand(0, 100);
// 不能存在文件中,因为有可能同时有多个用户使用
// file_put_contents('number.txt', $num);
// 因为 cookie 是每个用户自己保存,每个用户存的是属于自己的要猜的数字
setcookie('num', $num);
} else {
// 用户来试一试 猜了一次
// 还是通过cookie记录之前输入的内容
$count = empty($_COOKIE['count']) ? 0 : (int)$_COOKIE['count'];
if ($count < 10) {
// 对比用户提交的数字和用户 Cookie 中存放的被猜的数字
// $_GET['num'] => 用户试一试的数字
// $_COOKIE['num'] => 被猜的数字
$result = (int)$_GET['num'] - (int)$_COOKIE['num'];
if ($result == 0) {
$message = '猜对了';
// 重新开始,删除cookie即可
setcookie('num');
setcookie('count');
} elseif ($result > 0) {
$message = '太大了';
} else {
$message = '太小了';
}
setcookie('count', $count + 1);
} else {
// 游戏结束
$message = 'looooooooooooow!';
setcookie('num');
setcookie('count');
}
}
// ============== 判断 请求方式 辨别是第几次请求 ====================================
// if ($_SERVER['REQUEST_METHOD'] === 'GET') {
// // 在游戏开始时执行生成随机数
// $num = rand(0, 100);
// // 不能存在文件中,因为有可能同时有多个用户使用
// // file_put_contents('number.txt', $num);
// // 因为 cookie 是每个用户自己保存,每个用户存的是属于自己的要猜的数字
// setcookie('num', $num);
// } else {
// // 用户来试一试
// // 对比用户提交的数字和用户 Cookie 中存放的被猜的数字
// // $_POST['num'] => 用户试一试的数字
// // $_COOKIE['num'] => 被猜的数字
// $result = (int)$_POST['num'] - (int)$_COOKIE['num'];
// if ($result == 0) {
// echo '猜对了';
// } elseif ($result > 0) {
// echo '太大了';
// } else {
// echo '太小了';
// }
// }
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>猜数字</title>
<style>
body {
padding: 100px 0;
background-color: #2b3b49;
color: #fff;
text-align: center;
font-size: 2.5em;
}
input {
padding: 5px 20px;
height: 50px;
background-color: #3b4b59;
border: 1px solid #c0c0c0;
box-sizing: border-box;
color: #fff;
font-size: 20px;
}
button {
padding: 5px 20px;
height: 50px;
font-size: 16px;
}
</style>
</head>
<body>
<h1>猜数字游戏</h1>
<p>Hi,我已经准备了一个0~100的数字,你需要在仅有的10机会之内猜对它。</p>
<?php if (isset($message)): ?>
<p><?php echo $message; ?></p>
<?php endif ?>
<form action="index.php" method="get">
<input type="number" min="0" max="100" name="num" placeholder="随便猜">
<button type="submit">试一试</button>
</form>
</body>
</html>
效果;
但是cookie不太安全,可以从开发者选项看到随机数:
用session解决:
<?php
// 找一个属于当前访问者的箱子
// 并且把箱子的钥匙(session_id)交给用户(cookie)
session_start();
if (empty($_SESSION['num']) || empty($_GET['num'])) {
$num = rand(0, 100);
// 存在 cookie 中不保险,存在服务端的箱子里
$_SESSION['num'] = $num;
} else {
$count = empty($_SESSION['count']) ? 0 : $_SESSION['count'];
if ($count < 10) {
$result = (int)$_GET['num'] - $_SESSION['num'];
if ($result == 0) {
$message = '猜对了';
unset($_SESSION['num']);
unset($_SESSION['count']);
} elseif ($result > 0) {
$message = '太大了';
} else {
$message = '太小了';
}
$_SESSION['count'] = $count + 1;
} else {
$message = 'looooooooooooow!';
unset($_SESSION['num']);
unset($_SESSION['count']);
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>猜数字</title>
<style>
body {
padding: 100px 0;
background-color: #2b3b49;
color: #fff;
text-align: center;
font-size: 2.5em;
}
input {
padding: 5px 20px;
height: 50px;
background-color: #3b4b59;
border: 1px solid #c0c0c0;
box-sizing: border-box;
color: #fff;
font-size: 20px;
}
button {
padding: 5px 20px;
height: 50px;
font-size: 16px;
}
</style>
</head>
<body>
<h1>猜数字游戏</h1>
<p>Hi,我已经准备了一个0~100的数字,你需要在仅有的10机会之内猜对它。</p>
<?php if (isset($message)): ?>
<p><?php echo $message; ?></p>
<?php endif ?>
<form action="session.php" method="get">
<input type="number" min="0" max="100" name="num" placeholder="随便猜">
<button type="submit">试一试</button>
</form>
</body>
</html>
总结
七期的学习到此结束了,我们从如何建网站到现在的运用php技术完成小例子,这一路有很多艰辛。但是,大家仍然不能放松,更高深的知识还要自己去琢磨。那么,PHP到此结束。