今天学习了session cookie 然后通过session实现了用户的登录与退出。
案例目的:通过session,实现对用户登陆状态跟踪,从而实现登陆和登出,并且能够监听用户是否登陆后重复登陆。
实现过程:
新建login.php,然后html实现前端页面。用js事件绑定实现在前端的用户和密码的空值提示。这里的使用场景是在输入框失去焦点时提示,用户密码不能为空;输入框输入按下按键时,提示消失。都需要通过事件绑定,所以封装一个函数addEvent,传入三个参数,ele表示需要绑定事件的对象;tips是站位元素对象;msg是提示信息;这里用到了addEventListener方法目的是他可以重复绑定 然后分别绑定两个事件。
给登陆按钮添加点击事件,点击触发check方法。check主要是通过ajax方式将数据发送给check.php交互,通过POST的方式将username和password的数据发送过去,然后根据返回的状态码,将交互后的数据respond回来,这里先不做任何处理。
实例
<?php session_start();?> <?php if (isset($_SESSION['username'])): ?> <style>h2,p {text-align: center;margin-top: 50px;}</style> <h2 style="color:red">你已登录,请不要重复操作</h2> <p>正在跳转中...</p> <script> setTimeout("location.href = 'index.php'", 2000); </script> <?php else: ?> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录</title> <style> h3 { text-align: center; } div { width: 300px; height: 150px; /*background-color: lightblue;*/ margin: 0 auto; text-align: center; padding: 20px; border: 1px dashed #888; border-radius: 5%; } div input { border: none; border-bottom: 1px solid #333; } button:hover { cursor: pointer; background-color: lightblue; } .success { color: green; } .error { color: red; } </style> </head> <body> <h3>用户登录</h3> <div> <form name="user"> <p> <label>邮箱: <input type="email" name="username" placeholder="用户名"> </label> </p> <p> <label>密码: <input type="password" name="password" placeholder="密码"> </label> </p> <p> <button type="button" onclick="check(this.form)">登录</button> </p> <!-- 提示信息占位符 --> <p></p> </form> </div> </body> <script> // 获取表单 var user = document.forms.namedItem('user'); // 获取提示信息占位符 var tips = user.lastElementChild; // ele是触发时间的元素 // tips是占位元素 // msg错误提示信息 // console.log(user.username); function addEvent(ele,tips,msg) { ele.addEventListener('blur', function (){ if (this.value.trim().length === 0) { tips.classList.add('error'); tips.innerHTML = msg; this.focus(); } },false); ele.addEventListener('keydown', function () { tips.innerText = ''; },false); } // 给邮箱和密码元素添加事件 addEvent(user.username, tips, '邮箱不能为空'); addEvent(user.password, tips, '密码不能为空'); function check(form) { var request = new XMLHttpRequest(); request.onreadystatechange = function () { if (request.readyState===4 && request.status===200) { //将返回的json文本转成对象 var data = JSON.parse(request.responseText); //判断返回的json对象中的status值 如果是1 那么就代表登陆成功 if (data.status === 1) { // 先移除错误样式 tips.classList.remove('error'); // 添加正确的样式 正确的显示内容 tips.classList.add('success'); tips.innerText = data.message; // 2秒后跳转到首页 setTimeout(function(){ location.href = 'index.php'; }, 2000); } else { // 返回错误状态 显示错误提示样式及信息 tips.classList.add('error'); tips.innerText = data.message; } } }; request.open('POST', 'check.php', true); request.setRequestHeader('content-type','application/x-www-form-urlencoded'); var data = 'username='+form.username.value.trim()+'&password='+form.password.value; request.send(data); } </script> </html> <?php endif;?>
运行实例 »
点击 "运行实例" 按钮查看在线实例
3.新建check.php。先开启会话,用来将登陆成功后的id和username存储起来。然后进行邮箱和密码的再次非空验证,这里引入了$status=0 $message=空 两个变量,如果邮箱或密码为空,那么status为0,message为相应的字符串,通过json_encode变成json格式,方便login.php调用。
4.如果username和password都不为空,那么连接数据库,通过传过来的值同数据库中比对,如果相符那么count方法下通过fetchcolumn(0)必然>0,通过判断,然后再次通过准备对象执行数据库操作,将获取的数据对象赋给$user,然后再赋给session,然后将status值变为1,message变为登陆成功,转化成json数据以备login.php使用。
5.在login.php中,在ajax的第二步中,如果状态200 那么将json格式通过JSON.parse转化成对象data,判断data['status']为1的话 那么就让占位符添加成功样式,和提示信息,2秒后跳转到index.php,否则就给错误样式和提示信息
实例
<?php //print_r($_POST['username']); //开启会话 session_start(); //初始化两个值 $status = 0; $message = ''; //邮箱的非空验证 if (empty($_POST['username'])) { $message = '邮箱不能为空'; exit(json_encode(['status'=>$status, 'message'=>$message])); } else { $username = strtolower(trim($_POST['username'])); } //密码的非空验证 if (empty($_POST['password'])) { $message = '密码不能为空'; exit(json_encode(['status'=>$status, 'message'=>$message])); } else { $password = strtolower(trim($_POST['password'])); } if ($username && $password){ // 连接数据库 $pdo = new PDO('mysql:host=127.0.0.1;dbname=php', 'root', 'root'); $sql = 'SELECT COUNT(*) FROM `user` WHERE `email`=:email AND `password`=:password'; $stmt = $pdo->prepare($sql); // 执行sql语句并判断 if ($stmt->execute(['email'=>$username, 'password'=>$password])){ if ($stmt->fetchColumn(0) > 0){ $sql = 'SELECT `id`,`name` FROM `user` WHERE `email`=:email AND `password`=:password'; $stmt = $pdo->prepare($sql); $stmt->execute(['email'=>$username, 'password'=>$password]); $user = $stmt->fetch(PDO::FETCH_ASSOC); $_SESSION['user_id'] = $user['id']; $_SESSION['username'] = $user['name']; $status = 1; $message = '登录成功正在跳转'; exit(json_encode(['status'=>$status, 'message'=>$message])); } else{ $message = '邮箱密码错误'; exit(json_encode(['status'=>$status, 'message'=>$message])); } }else { die(print_r($stmt->errorInfo())); } }
运行实例 »
点击 "运行实例" 按钮查看在线实例
6.对login.php进行判断如果$_session['username']存在,那么就提示他已经登陆,跳转到index.php,否则进行登陆。
7.在index.php中设置用户及退出的样式,给退出添加点击事件,需要确认后在进行退出。确认后,通过logout.php进行登陆的session销毁。
实例
<?php session_start(); if (isset($_SESSION['username'])) { session_destroy(); setcookie('PHPSESSID', '', time()-3600, '/'); header('location:login.php'); }
运行实例 »
点击 "运行实例" 按钮查看在线实例
实例
<?php session_start()?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>瑾瑜网络 员工管理系统</title> <link href="css/bootstrap.min.css" rel="stylesheet"> <link href="css/styles.css" rel="stylesheet"> </head> <body> <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation"> <div class="container-fluid"> <div class="navbar-header"> <a class="navbar-brand" href="index.php"><span>瑾瑜</span>网络</a> <ul class="user-menu"> <li class="dropdown pull-right"> <?php if (isset($_SESSION['username'])):?> <a href="#" class="dropdown-toggle" ><span class="glyphicon glyphicon-user"></span> <?=$_SESSION['username'] ?></a> | <a href="javascript:return false" class="dropdown-toggle" onclick="return confirm('是否推出?')?location.assign('logout.php'):false ;" > 退出 </a> <?php else:?> <script>location.assign('login.php');</script> <?php endif; ?> </li> </ul> </div> </div><!-- /.container-fluid --> </nav> <div id="sidebar-collapse" class="col-sm-3 col-lg-2 sidebar"> <form role="search"> <div class="form-group"> <input type="text" class="form-control" placeholder="搜索"> </div> </form> <ul class="nav menu"> <li class="active"><a href="staff_list.php" target="workspace"><span class="glyphicon glyphicon-dashboard"></span> 员工管理</a></li> <li><a href="system.php" target="workspace"><span class="glyphicon glyphicon-th"></span> 系统设置</a></li> <li><a href="user_list.php" target="workspace"><span class="glyphicon glyphicon-stats"></span> 用户设置</a></li> </ul> <div class="attribution">版权所有 <a href="#" target="_blank" title="瑾瑜网络">@ 瑾瑜网络</a></div> </div><!--/.sidebar--> <div class="col-sm-9 col-sm-offset-3 col-lg-10 col-lg-offset-2 main"> <iframe src="staff_list.php" name="workspace" class="workspace"></iframe> </div> <!--/.main--> </body> </html>
运行实例 »
点击 "运行实例" 按钮查看在线实例
总结:这一节用到的知识点很多,从前端的js非空验证,ajax交互,后段的非空验证,post来的数据同数据库的比对然后用json返回,再根据返回的值进行判断和相应的操作。内容多,难度有点,重点做好业务逻辑的清晰。存在不足,重点记住js中元素的获取方式,ajax交互过程,连接数据库用count方法获取相应数据的个数以待判断,最后php中的变成json格式的json_encode方法和js中将json字符串变成对象的JSON.parse方法再次重申一遍。