Blogger Information
Blog 26
fans 0
comment 0
visits 21881
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
会话控制与实战
溪边小树
Original
676 people have browsed it

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,由服务器端设置,保存在服务器端。

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:你的理解完全正确
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post