该链接为这个实战的前置代码, https://www.php.cn/blog/detail/26509.html

在上次的基础上添加了登录,注册,退出登录的功能(有简单的验证,如邮箱格式), 并且实现了一个简单的权限管理(用户没有登录的情况下只能查看,不能操作).

效果

效果图

在之前的目录结构上新加了两个文件,修改了两个文件:

  • job
    • config
      • config.php
      • connect.php
    • controller
      • handle.php 修改
      • delete.php
      • select.php
      • update.php
    • pure-css3-icons
      • icono.min.css
    • event.js
    • style.css
    • index.php 修改
    • 数据表
    • 数据表1 用户表 新增
    • user-operation.js 新增
    • user-style.css 新增

controller" class="reference-link"><span id="1.2">controller</span>

handle.php" class="reference-link"><span id="1.2.1">handle.php</span>
  1. <?php
  2. session_start();
  3. $handle = $_GET['handle'] ?? $_POST['handle'] ?? 'select';
  4. //var_dump($_POST);
  5. //echo $handle;
  6. //die();
  7. switch ($handle) {
  8. case 'select':
  9. require __DIR__ . '/select.php';
  10. break;
  11. case 'update':
  12. require __DIR__ . '/update.php';
  13. break;
  14. case 'delete':
  15. require __DIR__ . '/delete.php';
  16. break;
  17. case 'login':
  18. require dirname(__DIR__) . '../config/connect.php';
  19. $pdo = connect();
  20. $sql = "SELECT email FROM `users` WHERE email=? AND password=md5(?);";
  21. $stmt = $pdo->prepare($sql);
  22. if ($stmt->execute([$_POST['email'], $_POST['password']])) {
  23. $data = $stmt->fetch();
  24. if (is_array($data) && count($data) === 1) {
  25. // 登录成功, 写入session
  26. $_SESSION['email'] = $_POST['email'];
  27. // 返回响应
  28. echo json_encode(['code' => 0, 'message' => '登录成功, 正在刷新页面....']);
  29. } else {
  30. echo json_encode(['code' => -20005, 'message' => '登录失败, 数据库中没有该用户,请注册!']);
  31. }
  32. } else {
  33. echo json_encode(['code' => $stmt->errorInfo()[0], 'message' => '未知错误, 请联系管理员. : ' . $stmt->errorInfo()[1]]);
  34. }
  35. break;
  36. case 'register':
  37. require dirname(__DIR__) . '../config/connect.php';
  38. $pdo = connect();
  39. $stmt = $pdo->prepare("SELECT email From `users`");
  40. $stmt->bindColumn('email', $email);
  41. $stmt->execute();
  42. $emailAyy = [];
  43. while ($stmt->fetch(PDO::FETCH_BOUND)) {
  44. $emailAyy[] = $email;
  45. }
  46. if (!in_array($_POST['email'], $emailAyy)) {
  47. $sql = "INSERT `users` SET username=?, email=?,password=md5(?)";
  48. $stmt = $pdo->prepare($sql);
  49. $stmt->execute([$_POST['username'], $_POST['email'], $_POST['password']]);
  50. if ($stmt->rowCount() === 1) {
  51. // 注册成功,自动登录
  52. $_SESSION['email'] = $_POST['email'];
  53. echo json_encode(['code' => 0, 'message' => '注册成功,正在跳转....']);
  54. } else {
  55. echo json_encode(['code' => 20004, 'message' => '未知错误,请联系管理员!']);
  56. }
  57. } else {
  58. echo json_encode(['code' => -20003, 'message' => '注册失败, 该邮箱已经注册过了!']);
  59. }
  60. break;
  61. case 'logout':
  62. // 清空session
  63. session_unset();
  64. // 删除session文件
  65. session_destroy();
  66. // 退出登录成功
  67. echo json_encode(['code' => 0, 'message' => '退成登录成功!']);
  68. break;
  69. default:
  70. exit('未知错误');
  71. }

index.php" class="reference-link"><span id="1.6">index.php</span>

  1. <?php session_start(); ?>
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>信息管理</title>
  7. <link rel="stylesheet" href="./pure-css3-icons/icono.min.css">
  8. <link rel="stylesheet" href="./style.css">
  9. <link rel="stylesheet" href="./user-style.css">
  10. </head>
  11. <body>
  12. <header>
  13. <a href="#">首页</a>
  14. <nav class="user-operation">
  15. <?php if (!isset($_SESSION['email'])): ?>
  16. <a data-handle="login">登录</a>
  17. <a data-handle="register">注册</a>
  18. <?php else: ?>
  19. <span><?= $_SESSION['email'] ?></span>
  20. <a data-handle="logout">退出登录</a>
  21. <?php endif; ?>
  22. </nav>
  23. </header>
  24. <table>
  25. <caption>信息管理</caption>
  26. <thead>
  27. <tr>
  28. <th>序号</th>
  29. <th>姓名</th>
  30. <th>性别</th>
  31. <th>年龄</th>
  32. <th>生日</th>
  33. <th>工资</th>
  34. <th>添加时间</th>
  35. <th>修改时间</th>
  36. <?php if (!empty($_SESSION['email'])) : ?>
  37. <th>操作</th>
  38. <?php endif; ?>
  39. </tr>
  40. </thead>
  41. <tbody class="tbody"></tbody>
  42. </table>
  43. <div class="paging"></div>
  44. <div class="masking">
  45. <div class="del-confirm">
  46. <header>
  47. <h3>警告</h3>
  48. <button onclick="delMaskingClose()"><i class="icono-cross"></i></button>
  49. </header>
  50. <masking-body>
  51. 确定删除
  52. </masking-body>
  53. <footer>
  54. <button onclick="delMaskingClose()">取消</button>
  55. <button onclick="delMaskingConfirm()">确定</button>
  56. </footer>
  57. </div>
  58. <div class="edit-confirm">
  59. <header>
  60. <h3>编辑</h3>
  61. <button onclick="editMaskingClose()"><i class="icono-cross"></i></button>
  62. </header>
  63. <masking-body class="edit-form">
  64. </masking-body>
  65. <footer>
  66. <button onclick="editMaskingClose()">取消</button>
  67. <button onclick="editMaskingConfirm()">确定</button>
  68. </footer>
  69. </div>
  70. </div>
  71. <div class="user-masking">
  72. <div class="user-login" style="display: block">
  73. <header>
  74. <h3>登录</h3>
  75. <button onclick="userMaskingClose()"><i class="icono-cross"></i></button>
  76. </header>
  77. <masking-body>
  78. <form id="login">
  79. <label for="email">邮箱: </label>
  80. <input type="email" name="email" id="email" required>
  81. <label for="password">密码: </label>
  82. <input type="password" name="password" id="password">
  83. <button type="button" class="user-submit" data-handle="login">登录</button>
  84. <span class="tip"></span>
  85. <a class="no-account">没有账号? 点击注册</a>
  86. </form>
  87. </masking-body>
  88. </div>
  89. <div class="user-register">
  90. <header>
  91. <h3>注册</h3>
  92. <button onclick="userMaskingClose()"><i class="icono-cross"></i></button>
  93. </header>
  94. <masking-body>
  95. <form id="register">
  96. <label for="username">用户名: </label>
  97. <input type="text" name="username" id="username">
  98. <label for="email">邮箱: </label>
  99. <input type="email" name="email" id="email">
  100. <label for="password">密码: </label>
  101. <input type="password" name="password" id="password">
  102. <label for="password1">确认密码: </label>
  103. <input type="password" name="password1" id="password1">
  104. <button type="button" class="user-submit" data-handle="register">注册</button>
  105. <span class="tip"></span>
  106. <a class="account">已有账号? 点击登录</a>
  107. </form>
  108. </masking-body>
  109. </div>
  110. </div>
  111. <script src="./event.js"></script>
  112. <script src="./user-operation.js"></script>
  113. </body>
  114. </html>

数据表" class="reference-link"><span id="1.8">数据表</span>

  1. /*
  2. Navicat MySQL Data Transfer
  3. Source Server : php_test
  4. Source Server Version : 50726
  5. Source Host : localhost:3306
  6. Source Database : phpedu
  7. Target Server Type : MYSQL
  8. Target Server Version : 50726
  9. File Encoding : 65001
  10. Date: 2021-03-02 17:04:52
  11. */
  12. SET FOREIGN_KEY_CHECKS=0;
  13. -- ----------------------------
  14. -- Table structure for users
  15. -- ----------------------------
  16. DROP TABLE IF EXISTS `users`;
  17. CREATE TABLE `users` (
  18. `uid` int(10) unsigned NOT NULL AUTO_INCREMENT,
  19. `username` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户名',
  20. `email` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '邮箱',
  21. `password` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '密码',
  22. `create_d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  23. PRIMARY KEY (`uid`),
  24. UNIQUE KEY `unique_email` (`email`)
  25. ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  26. -- ----------------------------
  27. -- Records of users
  28. -- ----------------------------
  29. INSERT INTO `users` VALUES ('1', 'admin', 'admin@qq.com', 'e10adc3949ba59abbe56e057f20f883e', '2021-03-02 16:28:15');
  30. INSERT INTO `users` VALUES ('2', 'zhangsan', 'zhangsan@qq.com', 'e10adc3949ba59abbe56e057f20f883e', '2021-03-02 16:43:23');

user-operation.js" class="reference-link"><span id="1.9">user-operation.js</span>

  1. const form = document.forms;
  2. const xhr = new XMLHttpRequest();
  3. const loginEmail = document.querySelector('#login #email');
  4. const loginPassword = document.querySelector('#login #password');
  5. const registerUsername = document.querySelector('#register #username');
  6. const registerEmail = document.querySelector('#register #email');
  7. const registerPassword = document.querySelector('#register #password');
  8. const registerPassword1 = document.querySelector('#register #password1');
  9. const loginTip = document.querySelector('#login .tip');
  10. const registerTip = document.querySelector('#register .tip');
  11. xhr.responseType = 'json';
  12. [loginEmail, loginPassword, registerUsername, registerEmail, registerPassword, registerPassword1]
  13. .forEach(item => item.oninput = () => [loginTip, registerTip].forEach(it => it.innerHTML = null));
  14. document.querySelector('.user-operation').addEventListener('click', function (ev) {
  15. ev.preventDefault();
  16. console.log(ev.target.getAttribute('data-handle'));
  17. switch (ev.target.getAttribute('data-handle')) {
  18. case 'login':
  19. document.querySelector('.user-masking').style.display = 'block';
  20. document.querySelector('.user-login').style.display = 'block';
  21. break;
  22. case 'register':
  23. document.querySelector('.user-masking').style.display = 'block';
  24. document.querySelector('.user-register').style.display = 'block';
  25. break;
  26. case 'logout':
  27. xhr.open('post', './Controller/handle.php?handle=logout');
  28. xhr.onload = () => {
  29. console.log(xhr.response);
  30. if (xhr.response.code === 0) {
  31. alert(xhr.response.message);
  32. location.href = 'index.php';
  33. }
  34. };
  35. xhr.onerror = (error) => console.log(error);
  36. xhr.send();
  37. break;
  38. default:
  39. alert('未知错误');
  40. }
  41. });
  42. document.querySelectorAll('.user-submit').forEach(item => item.addEventListener('click', function (ev) {
  43. console.log(ev.target.getAttribute('data-handle'));
  44. switch (ev.target.getAttribute('data-handle')) {
  45. case 'login':
  46. login();
  47. break;
  48. case 'register':
  49. register();
  50. break;
  51. default:
  52. alert('未知错误');
  53. }
  54. }));
  55. /**
  56. * 登录方法
  57. */
  58. function login() {
  59. const login = form.login;
  60. if (login.email.value.trim().length > 0) { // 判断邮箱是否有值
  61. // 判断邮箱格式是否正确
  62. if (/^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/.test(login.email.value.trim())) {
  63. if (login.password.value.trim().length > 0) { // 判断密码是否有值
  64. const formData = new FormData(login);
  65. formData.append('handle', 'login');
  66. xhr.open('post', './Controller/handle.php');
  67. xhr.onload = () => {
  68. console.log(xhr.response);
  69. loginTip.innerHTML = xhr.response.message;
  70. if (xhr.response.code === 0) {
  71. setTimeout(() => location.href = 'index.php', 2000);
  72. }
  73. };
  74. xhr.onerror = (error) => console.log(error);
  75. xhr.send(formData);
  76. } else {
  77. loginTip.innerHTML = '请输入密码!';
  78. login.password.focus();
  79. }
  80. } else {
  81. loginTip.innerHTML = '请输入正确格式的邮箱!';
  82. login.email.focus();
  83. }
  84. } else {
  85. loginTip.innerHTML = '请输入邮箱!';
  86. login.email.focus();
  87. }
  88. }
  89. /**
  90. * 注册方法
  91. */
  92. function register() {
  93. const register = form.register;
  94. console.log(register);
  95. if (register.username.value.trim().length > 0) { // 判断用户名是否有值
  96. if (register.email.value.trim().length > 0) { // 判断邮箱是否有值
  97. // 判断邮箱格式是否正确
  98. if (/^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/.test(register.email.value.trim())) {
  99. if (register.password.value.trim().length > 0) {// 判断密码是否有值
  100. if (register.password.value.trim() === register.password1.value.trim()) { // 判断两次密码是否相同
  101. const formData = new FormData(register);
  102. formData.delete('password1');
  103. formData.append('handle', 'register');
  104. xhr.open('post', './Controller/handle.php');
  105. xhr.onload = () => {
  106. console.log(xhr.response);
  107. registerTip.innerHTML = xhr.response.message;
  108. if (xhr.response.code === 0) {
  109. setTimeout(() => location.href = 'index.php', 2000);
  110. }
  111. };
  112. xhr.onerror = (error) => console.log(error);
  113. xhr.send(formData);
  114. } else {
  115. registerTip.innerHTML = '请保证二次输入的密码和依次输入的密码相同!';
  116. register.password.focus();
  117. }
  118. } else {
  119. registerTip.innerHTML = '请输入密码!';
  120. register.password.focus();
  121. }
  122. } else {
  123. registerTip.innerHTML = '请输入正确格式的邮箱!';
  124. register.email.focus();
  125. }
  126. } else {
  127. registerTip.innerHTML = '请输入邮箱!';
  128. register.email.focus();
  129. }
  130. } else {
  131. registerTip.innerHTML = '请输入用户名';
  132. register.username.focus();
  133. }
  134. }
  135. document.querySelector('.no-account').addEventListener('click', function (ev) {
  136. document.querySelector('.user-login').style.display = 'none';
  137. document.querySelector('.user-register').style.display = 'block';
  138. });
  139. document.querySelector('.account').addEventListener('click', function (ev) {
  140. document.querySelector('.user-login').style.display = 'block';
  141. document.querySelector('.user-register').style.display = 'none';
  142. });
  143. function userMaskingClose() {
  144. document.querySelector('.user-masking').style.display = 'none';
  145. document.querySelector('.user-login').style.display = 'none';
  146. document.querySelector('.user-register').style.display = 'none';
  147. }

user-style.css" class="reference-link"><span id="1.10">user-style.css</span>

  1. body > header {
  2. display: flex;
  3. align-self: stretch;
  4. padding: 0.5em 1em;
  5. background-color: #333333;
  6. }
  7. body > header > a {
  8. color: #bbbbbb;
  9. }
  10. body > header > nav {
  11. margin-left: auto;
  12. }
  13. body > header > nav a {
  14. color: #bbbbbb;
  15. }
  16. body > header a:hover {
  17. color: #ffffff;
  18. cursor: pointer;
  19. }
  20. .user-masking {
  21. position: fixed;
  22. top: 0;
  23. right: 0;
  24. bottom: 0;
  25. left: 0;
  26. background-color: rgba(0, 0, 0, .5);
  27. display: none;
  28. }
  29. .user-masking .user-login,
  30. .user-masking .user-register {
  31. width: 446px;
  32. height: 272px;
  33. background-color: #f4eded;
  34. border-radius: 1em;
  35. position: absolute;
  36. margin: auto;
  37. top: 0;
  38. right: 0;
  39. bottom: 0;
  40. left: 0;
  41. display: none;
  42. }
  43. .user-masking .user-register{
  44. height: 342px;
  45. }
  46. .user-masking header {
  47. display: flex;
  48. justify-content: space-between;
  49. align-items: center;
  50. padding: 8px 16px;
  51. border-bottom: 1px solid #3a3a3a;
  52. }
  53. .user-masking header button {
  54. background-color: transparent;
  55. border: none;
  56. height: 34px;
  57. width: 50px;
  58. cursor: pointer;
  59. }
  60. .user-masking masking-body {
  61. height: calc(100% - 50px);
  62. display: block;
  63. padding: 16px;
  64. }
  65. .user-masking masking-body form > label {
  66. /*place-self: center;*/
  67. text-align: left;
  68. line-height: 2em;
  69. }
  70. .user-masking masking-body form > input{
  71. padding: 0 .5em;
  72. line-height: 2em;
  73. }
  74. .user-masking masking-body form {
  75. display: grid;
  76. gap: .5em 0;
  77. width: 100%;
  78. padding: 1em 1em;
  79. grid-template-columns: 4.5em 1fr;
  80. }
  81. .user-submit{
  82. grid-area: span 1 / span 2;
  83. place-self: center;
  84. border: none;
  85. border-radius: .25em;
  86. background-color: #3485FB;
  87. padding: .5em 1em;
  88. }
  89. .tip{
  90. grid-area: span 1 / span 2;
  91. place-self: center;
  92. }
  93. .no-account,
  94. .account{
  95. grid-area: span 1 / span 2;
  96. place-self: center;
  97. }
  98. .no-account:hover,
  99. .account:hover{
  100. color: #7f007f;
  101. cursor: pointer;
  102. }

更多相关文章

  1. 【asp.net core 系列】- 11 Service层的实现样板
  2. 辣鸡,使用CAS机制完成SSO
  3. cookie在二级域名间共享完成sso
  4. 详解微信小程序登录wx.login(Object object)
  5. 【Nest教程】Nest项目配置邮件服务器,实现发送邮件
  6. 功能测试——app测试要点最全分析
  7. 克隆虚拟机和相互登录
  8. 一套简单通用的Java后台管理系统,拿来即用,非常方便(附项目地址)
  9. 最新工具:某网盘不限速下载器KinhDown,下载速度可达10MB/S

随机推荐

  1. Android(安卓)EditText限制输入两位小数
  2. Android开发网上的一些重要知识点_2
  3. Android(安卓)Notification 基础
  4. android点击事件穿透
  5. Android(安卓)aidl Binder框架浅析
  6. android 笔记 --- 相机应用
  7. aFinal框架
  8. android开发技巧精髓十
  9. Android(安卓)Volley完全解析(二),使用Vol
  10. android (20)