博客列表 >会话控制与实战

会话控制与实战

溪边小树
溪边小树原创
2020年05月27日 16:19:31674浏览

1. 会话控制

  • HTTP 是基于无连接的网络协议, 每一次访问, 对于服务器来说, 都是全新的
  • 如果记住访问者,以及记录连接状态, 可以提升用户体验,完成许多个性化的功能
  • 例如, 用户登录, 购物车等
  • 其实让服务器记住用户的方式很简单, 就和生活中, 我们办会员卡是一样的
  • 会员卡的存储位置有二个地方, 要么放在你身上, 要么保存到商家电脑中
  • 所以, 网络中的用户资料也会保存在二个地方: 浏览器(客户端)和服务器中
  • 保存到浏览器中的叫: cookie
  • 保存到服务器中的叫: session

  • 保存在客户端
  • 变量: $_COOKIE
  • 变量过滤器: filter_input(INPUT_COOKIE, key)
  • 设置使用专用函数: setcookie(名称, 值, 过期时间)
  • 生效需要分二步完成: 先下达指令到浏览器, 再由浏览器完成 cookie 写入

3. SESSION

  • 保存在服务器端
  • 变量: $_SESSION
  • 变量过滤器: filter_input(INPUT_SESSION, key)
  • 设置使用专用函数: setcookie(名称, 值, 过期时间)
  • 生效需要分二步完成: 先下达指令到浏览器, 再由浏览器完成 cookie 写入

示例演示

  1. <?php
  2. session_start();
  3. // cookie
  4. // 设置: 由服务器设置到浏览器, 理解成商城给用户发了一个会员卡
  5. setcookie('username', 'perter-zhu', time()+60, '/');
  6. // 查询
  7. echo $_COOKIE['username'];
  8. // 更新
  9. $_COOKIE['username'] = 'admin';
  10. setcookie('username', 'admin', time()+60, '/');
  11. echo $_COOKIE['username'];
  12. // 删除
  13. setcookie('username', null, time()-60, '/');
  14. echo $_SESSION['email'];
  15. --------------------------------------------
  16. // session: 会话, 将客户端信息保存到服务器上
  17. // 向用户发会员卡, 启动一个会话
  18. session_start();
  19. // 1. 给浏览器发一个id用来标识用户:session_id(), PHPSESSID
  20. // 2. 在服务器上指定位置保存与用户id对应的用户信息
  21. // sess_ku7neaha636g69t4mq0atj6d2i
  22. // ku7neaha636g69t4mq0atj6d2i
  23. $_SESSION['email'] ='admin@php.cn';
  24. $_SESSION['password'] = sha1(md5('1234567'). 'php.cn123');
  25. $_SESSION['email'] ='peter@php.cn';
  26. session_destroy();
  27. setcookie('PHPSESSID', '', time()-123456);

index.php

  1. // 判断是否已经登录?
  2. if (isset($_COOKIE['user'])) $user = unserialize($_COOKIE['user']);
  3. ?>
  4. <!DOCTYPE html>
  5. <html lang="en">
  6. <head>
  7. <meta charset="UTF-8">
  8. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  9. <link rel="stylesheet" type="text/css" href="../css/index.css">
  10. <title>首页</title>
  11. </head>
  12. <body>
  13. <nav>
  14. <a href="index.php">我的论坛</a>
  15. <?php if (isset($user)) : ?>
  16. <a href="" id="logout"><span style="color:red"><?php echo $user['name']?></span>&nbsp;&nbsp;退出</a>
  17. <?php else: ?>
  18. <a href="login.php">登录</a>
  19. <?php endif ?>
  20. </nav>
  21. </body>
  22. <script>
  23. // 为退出按钮创建事件监听器
  24. document.querySelector('#logout').addEventListener('click', function(event) {
  25. if (confirm('是否退出')) {
  26. // 禁用默认行为, 其实就是禁用原<a>标签的点击跳转行为,使用事件中的自定义方法处理
  27. event.preventDefault();
  28. // 跳转到退出事件处理器
  29. window.location.assign('handle.php?action=logout');
  30. }
  31. });
  32. </script>
  33. </html>

login.php

  1. <?php
  2. // 判断是否已登录
  3. if (isset($_COOKIE['user']))
  4. exit('<script>alert("请不要重复登录");location.href="index.php";</script>');
  5. ?>
  6. <!DOCTYPE html>
  7. <html lang="en">
  8. <head>
  9. <meta charset="UTF-8">
  10. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  11. <link rel="stylesheet" type="text/css" href="../css/style.css">
  12. <title>用户登录</title>
  13. </head>
  14. <body>
  15. <!-- 只需要验证用户的邮箱和密码就可以 -->
  16. <h3>用户登录</h3>
  17. <form action="handle.php?action=login" method="post">
  18. <div>
  19. <label for="email">邮箱:</label>
  20. <input type="email" name="email" id="email" placeholder="demo@email.com" require autofocus>
  21. </div>
  22. <div>
  23. <label for="password">密码:</label>
  24. <input type="password" name="password" id="password" placeholder="不少于6位" required>
  25. </div>
  26. <div>
  27. <button>提交</button>
  28. </div>
  29. </form>
  30. <a href="register.php">还没有帐号, 注册一个吧</a>
  31. </body>
  32. </html>

register.php

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <link rel="stylesheet" type="text/css" href="../css/style.css">
  7. <title>注册用户</title>
  8. </head>
  9. <body>
  10. <h3>用户注册</h3>
  11. <form action="handle.php?action=register" method="post" onsubmit="return compare()">
  12. <div>
  13. <label for="name">呢称:</label>
  14. <input type="text" name="name" id="name" placeholder="不少于3个字符" required autofocus>
  15. </div>
  16. <div>
  17. <label for="email">邮箱:</label>
  18. <input type="email" name="email" id="email" placeholder="demo@email.com" required>
  19. </div>
  20. <div>
  21. <label for="p1">密码:</label>
  22. <input type="password" name="p1" id="p1" placeholder="不少于6位" required>
  23. </div>
  24. <div>
  25. <label for="p2">重复:</label>
  26. <input type="password" name="p2" id="p2" placeholder="必须与上面一致" required>
  27. </div>
  28. <div>
  29. <button>提交</button><span id="tips" style="color: red"></span>
  30. </div>
  31. </form>
  32. <a href="login.php">我有帐号,直接登录</a>
  33. <script>
  34. // 验证二次密码是否相等?
  35. function compare() {
  36. if (document.forms[0].p1.value.trim() !== document.forms[0].p2.value.trim()) {
  37. document.querySelector('#tips').innerText = '二次密码不相等';
  38. return false;
  39. }
  40. }
  41. </script>
  42. </body>
  43. </html>

handle.php

  1. <?php
  2. // 查询用户表中的数据
  3. $pdo = new PDO('mysql:host=localhost;dbname=phpedu', 'root', 'root');
  4. $stmt = $pdo->prepare('SELECT * FROM `users`');
  5. $stmt->execute();
  6. $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
  7. // 处理用户登录与注册
  8. $action = $_GET['action'];
  9. switch ( strtolower($action)) {
  10. // 登录
  11. case 'login':
  12. // 判断请求是否合t法
  13. if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  14. // 获取需要验证的数据
  15. $email = $_POST['email'];
  16. $password = sha1($_POST['password']);
  17. $results = array_filter($users, function($user) use ($email, $password) {
  18. return $user['email'] === $email && $user['password'] === $password;
  19. });
  20. if (count($results) === 1) {
  21. setcookie('user', serialize(array_pop($results)));
  22. exit('<script>alert("验证通过");location.href="index.php"</script>');
  23. } else {
  24. exit('<script>alert("邮箱或密码错误,或者还没有帐号");location.href="login.php";</script>');
  25. }
  26. } else {
  27. die('请求类型错误');
  28. }
  29. break;
  30. // 退出
  31. case 'logout':
  32. if (isset($_COOKIE['user'])) {
  33. setcookie('user', null , time()-3600);
  34. exit('<script>alert("退出成功");location.assign("index.php")</script>');
  35. }
  36. break;
  37. // 注册
  38. case 'register':
  39. // 1. 获取到所有新用户数据
  40. $name = $_POST['name'];
  41. $email = $_POST['email'];
  42. $password = sha1($_POST['p1']);
  43. $register_time = time();
  44. // 2. 将新用户插入到表中
  45. $sql = "INSERT `users` SET `name`='{$name}', `email`='{$email}', `password`='{$password}', `register_time`={$register_time}";
  46. $stmt = $pdo->prepare($sql);
  47. $stmt->execute();
  48. if ($stmt->rowCount() === 1) exit('<script>alert("注册成功");location.assign("login.php")</script>');
  49. else exit('<script>alert("注册失败");location.assign("login.php")</script>');
  50. break;
  51. // 未定义
  52. default:
  53. exit('未定义操作');
  54. }

index.css

  1. nav {
  2. height: 40px;
  3. background-color: deepskyblue;
  4. padding: 0 20px;
  5. display: flex;
  6. justify-content: space-between;
  7. align-items: center;
  8. }
  9. nav > a {
  10. color: white;
  11. text-decoration: none;
  12. }

style.css

  1. body {
  2. display: flex;
  3. flex-direction: column;
  4. text-align: center;
  5. color: #555;
  6. font-weight: 300;
  7. }
  8. body h3 {
  9. font-weight: 300;
  10. font-size: 20px;
  11. margin-bottom: 10px;
  12. }
  13. body form {
  14. width: 220px;
  15. padding: 20px;
  16. box-sizing: border-box;
  17. background-color: skyblue;
  18. margin: auto;
  19. border-radius: 5px;
  20. box-shadow: 0 0 5px #aaa;
  21. }
  22. body form > div {
  23. height: 36px;
  24. display: flex;
  25. justify-content: space-between;
  26. align-items: center;
  27. }
  28. body form div:last-of-type {
  29. display: flex;
  30. justify-content: center;
  31. }
  32. body form input {
  33. border: none;
  34. outline: none;
  35. padding-left: 5px;
  36. height: 20px;
  37. }
  38. body form input:hover {
  39. box-shadow: 0 0 5px #aaa;
  40. }
  41. body form button {
  42. flex: auto;
  43. height: 30px;
  44. background-color: green;
  45. color: white;
  46. border: none;
  47. outline: none;
  48. }
  49. body form button:hover {
  50. background-color: lightcoral;
  51. cursor: pointer;
  52. box-shadow: 0 0 5px #aaa;
  53. }
  54. body a {
  55. color: #888;
  56. text-decoration: none;
  57. margin-top: 15px;
  58. }
  59. body a:hover {
  60. color: lightcoral;
  61. font-weight: bold;
  62. }

Session方式的用户登陆

index.php

  1. <?php
  2. // 开启会话
  3. session_start();
  4. // 判断是否已经登录?
  5. if (isset($_SESSION['user'])) $user = unserialize($_SESSION['user']);
  6. ?>
  7. <!DOCTYPE html>
  8. <html lang="en">
  9. <head>
  10. <meta charset="UTF-8">
  11. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  12. <link rel="stylesheet" type="text/css" href="../css/index.css">
  13. <title>首页</title>
  14. </head>
  15. <body>
  16. <nav>
  17. <a href="index.php">我的论坛</a>
  18. <?php if (isset($user)) : ?>
  19. <a href="" id="logout"><span style="color:red"><?php echo $user['name']?></span>&nbsp;&nbsp;退出</a>
  20. <?php else: ?>
  21. <a href="login.php">登录</a>
  22. <?php endif ?>
  23. </nav>
  24. </body>
  25. <script>
  26. // 为退出按钮创建事件监听器
  27. document.querySelector('#logout').addEventListener('click', function(event) {
  28. if (confirm('是否退出')) {
  29. // 禁用默认行为, 其实就是禁用原<a>标签的点击跳转行为,使用事件中的自定义方法处理
  30. event.preventDefault();
  31. // 跳转到退出事件处理器
  32. window.location.assign('handle.php?action=logout');
  33. }
  34. });
  35. </script>
  36. </html>

login.php

  1. <?php
  2. // 开启会话
  3. session_start();
  4. // 判断是否已登录
  5. if (isset($_SESSION['user']))
  6. exit('<script>alert("请不要重复登录");location.href="index.php";</script>');
  7. ?>
  8. <!DOCTYPE html>
  9. <html lang="en">
  10. <head>
  11. <meta charset="UTF-8">
  12. <title>用户登录</title>
  13. <link rel="stylesheet" type="text/css" href="../css/style.css">
  14. </head>
  15. <body>
  16. <h3>用户登录</h3>
  17. <form action="handle.php?action=login" method="post">
  18. <div>
  19. <label for="email">邮箱:</label>
  20. <input type="email" name="email" id="email" placeholder="demo@email.com" required autofocus>
  21. </div>
  22. <div>
  23. <label for="password">密码:</label>
  24. <input type="password" name="password" id="password" placeholder="不少于6位" required>
  25. </div>
  26. <div>
  27. <button>提交</button>
  28. </div>
  29. </form>
  30. <a href="register.php">还没有帐号, 注册一个吧</a>
  31. </body>
  32. </html>

register.php

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <link rel="stylesheet" type="text/css" href="../css/style.css">
  7. <title>注册用户</title>
  8. </head>
  9. <body>
  10. <h3>用户注册</h3>
  11. <form action="handle.php?action=register" method="post" onsubmit="return compare()">
  12. <div>
  13. <label for="name">呢称:</label>
  14. <input type="text" name="name" id="name" placeholder="不少于3个字符" required autofocus>
  15. </div>
  16. <div>
  17. <label for="email">邮箱:</label>
  18. <input type="email" name="email" id="email" placeholder="demo@email.com" required>
  19. </div>
  20. <div>
  21. <label for="p1">密码:</label>
  22. <input type="password" name="p1" id="p1" placeholder="不少于6位" required>
  23. </div>
  24. <div>
  25. <label for="p2">重复:</label>
  26. <input type="password" name="p2" id="p2" placeholder="必须与上面一致" required>
  27. </div>
  28. <div>
  29. <button>提交</button><span id="tips" style="color: red"></span>
  30. </div>
  31. </form>
  32. <a href="login.php">我有帐号,直接登录</a>
  33. <script>
  34. // 验证二次密码是否相等?
  35. function compare() {
  36. if (document.forms[0].p1.value.trim() !== document.forms[0].p2.value.trim()) {
  37. document.querySelector('#tips').innerText = '二次密码不相等';
  38. return false;
  39. }
  40. }
  41. </script>
  42. </body>
  43. </html>

handle.php

  1. <?php
  2. // 开启会话
  3. session_start();
  4. // 查询用户表中的数据
  5. $pdo = new PDO('mysql:host=localhost;dbname=phpedu', 'root', 'root');
  6. $stmt = $pdo->prepare('SELECT * FROM `users`');
  7. $stmt->execute();
  8. $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
  9. // 处理用户登录与注册
  10. $action = $_GET['action'];
  11. switch ( strtolower($action)) {
  12. // 登录
  13. case 'login':
  14. // 判断请求是否合t法
  15. if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  16. // 获取需要验证的数据
  17. $email = $_POST['email'];
  18. $password = sha1($_POST['password']);
  19. $results = array_filter($users, function($user) use ($email, $password) {
  20. return $user['email'] === $email && $user['password'] === $password;
  21. });
  22. if (count($results) === 1) {
  23. $_SESSION['user'] = serialize(array_pop($results));
  24. exit('<script>alert("验证通过");location.href="index.php"</script>');
  25. } else {
  26. exit('<script>alert("邮箱或密码错误,或者还没有帐号");location.href="login.php";</script>');
  27. }
  28. } else {
  29. die('请求类型错误');
  30. }
  31. break;
  32. // 退出
  33. case 'logout':
  34. if (isset($_SESSION['user'])) {
  35. session_destroy();
  36. exit('<script>alert("退出成功");location.assign("index.php")</script>');
  37. }
  38. break;
  39. // 注册
  40. case 'register':
  41. // 1. 获取到所有新用户数据
  42. $name = $_POST['name'];
  43. $email = $_POST['email'];
  44. $password = sha1($_POST['p1']);
  45. $register_time = time();
  46. // 2. 将新用户插入到表中
  47. $sql = "INSERT `users` SET `name`='{$name}', `email`='{$email}', `password`='{$password}', `register_time`={$register_time}";
  48. $stmt = $pdo->prepare($sql);
  49. $stmt->execute();
  50. if ($stmt->rowCount() === 1) exit('<script>alert("注册成功");location.assign("login.php")</script>');
  51. else exit('<script>alert("注册失败");location.assign("login.php")</script>');
  52. break;
  53. // 未定义
  54. default:
  55. exit('未定义操作');
  56. }
  57. index.css
  58. ```css
  59. nav {
  60. height: 40px;
  61. background-color: deepskyblue;
  62. padding: 0 20px;
  63. display: flex;
  64. justify-content: space-between;
  65. align-items: center;
  66. }
  67. nav > a {
  68. color: white;
  69. text-decoration: none;
  70. }

style.css

  1. body {
  2. display: flex;
  3. flex-direction: column;
  4. text-align: center;
  5. color: #555;
  6. font-weight: 300;
  7. }
  8. body h3 {
  9. font-weight: 300;
  10. font-size: 20px;
  11. margin-bottom: 10px;
  12. }
  13. body form {
  14. width: 220px;
  15. padding: 20px;
  16. box-sizing: border-box;
  17. background-color: skyblue;
  18. margin: auto;
  19. border-radius: 5px;
  20. box-shadow: 0 0 5px #aaa;
  21. }
  22. body form > div {
  23. height: 36px;
  24. display: flex;
  25. justify-content: space-between;
  26. align-items: center;
  27. }
  28. body form div:last-of-type {
  29. display: flex;
  30. justify-content: center;
  31. }
  32. body form input {
  33. border: none;
  34. outline: none;
  35. padding-left: 5px;
  36. height: 20px;
  37. }
  38. body form input:hover {
  39. box-shadow: 0 0 5px #aaa;
  40. }
  41. body form button {
  42. flex: auto;
  43. height: 30px;
  44. background-color: green;
  45. color: white;
  46. border: none;
  47. outline: none;
  48. }
  49. body form button:hover {
  50. background-color: lightcoral;
  51. cursor: pointer;
  52. box-shadow: 0 0 5px #aaa;
  53. }
  54. body a {
  55. color: #888;
  56. text-decoration: none;
  57. margin-top: 15px;
  58. }
  59. body a:hover {
  60. color: lightcoral;
  61. font-weight: bold;
  62. }

课程学习小结

本次课程老师讲解非常细致,在老师的直播讲解之后,又通过回看视频进行理解消化,并在老师的课堂案例中实操了每一段代码予以加深理解,对用户登陆处理环节有了比较完整的认识,对以前不太敢看的整段代码,能够认真地看完并基本理解,有一定的进步。
复习过程中对本次课程中关于会话控制相关原理知识要点做了整理:Cookie:服务器端设置、保存在客户端的一个小变量,用来标识访问者的身份,是针对浏览器的,它不认识你是张三还是李四,它只认识你用的是什么样的访问代理,就是你用的是什么样的浏览器,它通过识别浏览器来识别当前访问用户是不是已经访问过了,如果你是第二次来,那我读一下看里面有没有Cookie,有的话就把它取出来,取到之后就知道你是否已经登录了,根据Cookie的值来进行判断,这就是一个典型的会话过程。Cookie类似于超市会员卡,实际卡片保存在用户手中(浏览器端),但随着发展,如果是电子卡包或只报手机号,就变成了存在商家手中(服务器端),这就是Session了。我们一般所说的会话控制,主要指的是Session,由服务器端设置,保存在服务器端。

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议